From 94e811f0f16fc3c81ddeaec579a517678833e786 Mon Sep 17 00:00:00 2001 From: claravanstaden Date: Tue, 7 Jan 2025 14:43:19 +0200 Subject: [PATCH] add deleted files --- .github/.markdownlint.yaml | 210 ++++++++++++++++++ .github/ISSUE_TEMPLATE/blank.md | 4 + .github/ISSUE_TEMPLATE/bug_report.yaml | 35 +++ .github/ISSUE_TEMPLATE/config.yml | 7 + .github/ISSUE_TEMPLATE/feature.yaml | 55 +++++ .github/runtime_specs/rococo.json | 17 ++ .github/runtime_specs/westend.json | 17 ++ .github/scripts/check-prdoc.py | 71 ++++++ .github/scripts/check-runtime.py | 124 +++++++++++ .github/scripts/check-workspace.py | 175 +++++++++++++++ .github/workflows/gitspiegel-trigger.yml | 35 +++ .../workflows/issues-auto-add-parachain.yml | 30 +++ .github/workflows/issues-auto-label.yml | 17 ++ .../workflows/misc-notify-burnin-label.yml | 24 ++ .../workflows/misc-review-bot-merge-queue.yml | 25 +++ .../workflows/release-99_notif-published.yml | 50 +++++ .github/workflows/review-trigger.yml | 73 ++++++ 17 files changed, 969 insertions(+) create mode 100644 .github/.markdownlint.yaml create mode 100644 .github/ISSUE_TEMPLATE/blank.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature.yaml create mode 100644 .github/runtime_specs/rococo.json create mode 100644 .github/runtime_specs/westend.json create mode 100644 .github/scripts/check-prdoc.py create mode 100755 .github/scripts/check-runtime.py create mode 100644 .github/scripts/check-workspace.py create mode 100644 .github/workflows/gitspiegel-trigger.yml create mode 100644 .github/workflows/issues-auto-add-parachain.yml create mode 100644 .github/workflows/issues-auto-label.yml create mode 100644 .github/workflows/misc-notify-burnin-label.yml create mode 100644 .github/workflows/misc-review-bot-merge-queue.yml create mode 100644 .github/workflows/release-99_notif-published.yml create mode 100644 .github/workflows/review-trigger.yml diff --git a/.github/.markdownlint.yaml b/.github/.markdownlint.yaml new file mode 100644 index 000000000000..6a93d89c46ad --- /dev/null +++ b/.github/.markdownlint.yaml @@ -0,0 +1,210 @@ +# Default state for all rules +default: true + +# Path to configuration file to extend +extends: null + +# MD001/heading-increment/header-increment - Heading levels should only increment by one level at a time +MD001: true + +# MD002/first-heading-h1/first-header-h1 - First heading should be a top-level heading +MD002: + # Heading level + level: 1 + +# MD003/heading-style/header-style - Heading style +MD003: + # Heading style + style: "consistent" + +# MD004/ul-style - Unordered list style +MD004: + # List style + style: "consistent" + +# MD005/list-indent - Inconsistent indentation for list items at the same level +MD005: false + +# MD006/ul-start-left - Consider starting bulleted lists at the beginning of the line +MD006: false + +# MD007/ul-indent - Unordered list indentation +MD007: false + +# MD009/no-trailing-spaces - Trailing spaces +MD009: + # Spaces for line break + br_spaces: 2 + # Allow spaces for empty lines in list items + list_item_empty_lines: false + # Include unnecessary breaks + strict: false + +# MD010/no-hard-tabs - Hard tabs +MD010: false + +# MD011/no-reversed-links - Reversed link syntax +MD011: true + +# MD012/no-multiple-blanks - Multiple consecutive blank lines +MD012: + # Consecutive blank lines + maximum: 2 + +# MD013/line-length - Line length +MD013: + # Number of characters + line_length: 120 + # Number of characters for headings + heading_line_length: 120 + # Number of characters for code blocks + code_block_line_length: 150 + # Include code blocks + code_blocks: true + # Include tables + tables: true + # Include headings + headings: true + # Include headings + headers: true + # Strict length checking + strict: false + # Stern length checking + stern: false + +# MD014/commands-show-output - Dollar signs used before commands without showing output +MD014: true + +# MD018/no-missing-space-atx - No space after hash on atx style heading +MD018: true + +# MD019/no-multiple-space-atx - Multiple spaces after hash on atx style heading +MD019: true + +# MD020/no-missing-space-closed-atx - No space inside hashes on closed atx style heading +MD020: true + +# MD021/no-multiple-space-closed-atx - Multiple spaces inside hashes on closed atx style heading +MD021: true + +# MD022/blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines +MD022: false + +# MD023/heading-start-left/header-start-left - Headings must start at the beginning of the line +MD023: true + +# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content +MD024: false + +# MD025/single-title/single-h1 - Multiple top-level headings in the same document +MD025: false + +# MD026/no-trailing-punctuation - Trailing punctuation in heading +MD026: + # Punctuation characters + punctuation: ".,;:!。,;:!" + +# MD027/no-multiple-space-blockquote - Multiple spaces after blockquote symbol +MD027: true + +# MD028/no-blanks-blockquote - Blank line inside blockquote +MD028: true + +# MD029/ol-prefix - Ordered list item prefix +MD029: + # List style + style: "one_or_ordered" + +# MD030/list-marker-space - Spaces after list markers +MD030: + # Spaces for single-line unordered list items + ul_single: 1 + # Spaces for single-line ordered list items + ol_single: 1 + # Spaces for multi-line unordered list items + ul_multi: 1 + # Spaces for multi-line ordered list items + ol_multi: 1 + +# MD031/blanks-around-fences - Fenced code blocks should be surrounded by blank lines +MD031: false + +# MD032/blanks-around-lists - Lists should be surrounded by blank lines +MD032: false + +# MD033/no-inline-html - Inline HTML +MD033: false + +# MD034/no-bare-urls - Bare URL used +MD034: false + +# MD035/hr-style - Horizontal rule style +MD035: + # Horizontal rule style + style: "consistent" + +# MD036/no-emphasis-as-heading/no-emphasis-as-header - Emphasis used instead of a heading +MD036: false + +# MD037/no-space-in-emphasis - Spaces inside emphasis markers +MD037: true + +# MD038/no-space-in-code - Spaces inside code span elements +MD038: true + +# MD039/no-space-in-links - Spaces inside link text +MD039: true + +# MD040/fenced-code-language - Fenced code blocks should have a language specified +MD040: false + +# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: false + +# MD042/no-empty-links - No empty links +MD042: true + +# MD043/required-headings/required-headers - Required heading structure +MD043: false + +# MD044/proper-names - Proper names should have the correct capitalization +MD044: + # List of proper names + names: ["Polkadot", "Substrate", "Cumulus", "Parity"] + # Include code blocks + code_blocks: false + # Include HTML elements + html_elements: false + +# MD045/no-alt-text - Images should have alternate text (alt text) +MD045: false + +# MD046/code-block-style - Code block style +MD046: + # Block style + style: "consistent" + +# MD047/single-trailing-newline - Files should end with a single newline character +MD047: true + +# MD048/code-fence-style - Code fence style +MD048: + # Code fence style + style: "consistent" + +# MD049/emphasis-style - Emphasis style should be consistent +MD049: false + +# MD050/strong-style - Strong style should be consistent +MD050: + # Strong style + style: "consistent" + +# MD051/link-fragments - Link fragments should be valid +MD051: false + +# MD052/reference-links-images - Reference links and images should use a label that is defined +MD052: false + +# MD053/link-image-reference-definitions - Link and image reference definitions should be needed +MD053: false diff --git a/.github/ISSUE_TEMPLATE/blank.md b/.github/ISSUE_TEMPLATE/blank.md new file mode 100644 index 000000000000..2a9137e72802 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/blank.md @@ -0,0 +1,4 @@ +--- +name: New blank issue +about: New blank issue +--- diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 000000000000..f828a5d9d893 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,35 @@ +name: Bug Report +description: Let us know about an issue you experienced with this software +labels: [ I2-bug, I10-unconfirmed ] + +body: + - type: checkboxes + attributes: + label: Is there an existing issue? + description: Please search to see if an issue already exists and leave a comment that you also experienced this issue or add your specifics that are related to an existing issue. + options: + - label: I have searched the existing issues + required: true + - type: checkboxes + attributes: + label: Experiencing problems? Have you tried our Stack Exchange first? + description: Please search to see if an post already exists, and ask if not. Please do not file support issues here. + options: + - label: This is not a support question. + required: true + - type: textarea + id: bug + attributes: + label: Description of bug + description: What seems to be the problem? + # placeholder: Describe the problem. + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to reproduce + description: Provide the steps that led to the discovery of the issue. + # placeholder: Describe what you were doing so we can reproduce the problem. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000000..e422e317411f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,7 @@ +blank_issues_enabled: true +contact_links: + - name: Support & Troubleshooting with the Substrate Stack Exchange Community + url: https://substrate.stackexchange.com + about: | + For general problems with Substrate or related technologies, please search here first + for solutions, by keyword and tags. If you discover no solution, please then ask and questions in our community! We highly encourage everyone also share their understanding by answering questions for others. diff --git a/.github/ISSUE_TEMPLATE/feature.yaml b/.github/ISSUE_TEMPLATE/feature.yaml new file mode 100644 index 000000000000..828e8b461ccc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yaml @@ -0,0 +1,55 @@ +name: Feature Request +description: Submit your requests and suggestions to improve! +labels: [ I5-enhancement ] +body: + - type: checkboxes + id: existing + attributes: + label: Is there an existing issue? + description: Please search to see if an issue already exists and leave a comment that you also experienced this issue or add your specifics that are related to an existing issue. + options: + - label: I have searched the existing issues + required: true + - type: checkboxes + id: stackexchange + attributes: + label: Experiencing problems? Have you tried our Stack Exchange first? + description: Please search to see if an post already exists, and ask if not. Please do not file support issues here. + options: + - label: This is not a support question. + required: true + - type: textarea + id: motivation + attributes: + label: Motivation + description: Please give precedence as to what lead you to file this issue. + # placeholder: Describe ... + validations: + required: false + - type: textarea + id: request + attributes: + label: Request + description: Please describe what is needed. + # placeholder: Describe what you would like to see added or changed. + validations: + required: true + - type: textarea + id: solution + attributes: + label: Solution + description: If possible, please describe what a solution could be. + # placeholder: Describe what you would like to see added or changed. + validations: + required: false + - type: dropdown + id: help + attributes: + label: Are you willing to help with this request? + multiple: true + options: + - Yes! + - No. + - Maybe (please elaborate above) + validations: + required: true diff --git a/.github/runtime_specs/rococo.json b/.github/runtime_specs/rococo.json new file mode 100644 index 000000000000..6568b06400c8 --- /dev/null +++ b/.github/runtime_specs/rococo.json @@ -0,0 +1,17 @@ +{ + "pallets": { + "1": { + "constants": { + "EpochDuration": { + "value": [ 88, 2, 0, 0, 0, 0, 0, 0 ]} + } + }, + + "2": { + "constants": { + "MinimumPeriod": { + "value": [ 184, 11, 0, 0, 0, 0, 0, 0 ]} + } + } + } + } diff --git a/.github/runtime_specs/westend.json b/.github/runtime_specs/westend.json new file mode 100644 index 000000000000..6568b06400c8 --- /dev/null +++ b/.github/runtime_specs/westend.json @@ -0,0 +1,17 @@ +{ + "pallets": { + "1": { + "constants": { + "EpochDuration": { + "value": [ 88, 2, 0, 0, 0, 0, 0, 0 ]} + } + }, + + "2": { + "constants": { + "MinimumPeriod": { + "value": [ 184, 11, 0, 0, 0, 0, 0, 0 ]} + } + } + } + } diff --git a/.github/scripts/check-prdoc.py b/.github/scripts/check-prdoc.py new file mode 100644 index 000000000000..42b063f2885d --- /dev/null +++ b/.github/scripts/check-prdoc.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +''' +Ensure that the prdoc files are valid. + +# Example + +```sh +python3 -m pip install cargo-workspace +python3 .github/scripts/check-prdoc.py Cargo.toml prdoc/*.prdoc +``` + +Produces example output: +```pre +🔎 Reading workspace polkadot-sdk/Cargo.toml +📦 Checking 32 prdocs against 493 crates. +✅ All prdocs are valid +``` +''' + +import os +import yaml +import argparse +import cargo_workspace + +def check_prdoc_crate_names(root, paths): + ''' + Check that all crates of the `crates` section of each prdoc is present in the workspace. + ''' + + print(f'🔎 Reading workspace {root}.') + workspace = cargo_workspace.Workspace.from_path(root) + crate_names = [crate.name for crate in workspace.crates] + + print(f'📦 Checking {len(paths)} prdocs against {len(crate_names)} crates.') + faulty = {} + + for path in paths: + with open(path, 'r') as f: + prdoc = yaml.safe_load(f) + + for crate in prdoc.get('crates', []): + crate = crate['name'] + if crate in crate_names: + continue + + faulty.setdefault(path, []).append(crate) + + if len(faulty) == 0: + print('✅ All prdocs are valid.') + else: + print('❌ Some prdocs are invalid.') + for path, crates in faulty.items(): + print(f'💥 {path} lists invalid crate: {", ".join(crates)}') + exit(1) + +def parse_args(): + parser = argparse.ArgumentParser(description='Check prdoc files') + parser.add_argument('root', help='The cargo workspace manifest', metavar='root', type=str, nargs=1) + parser.add_argument('prdoc', help='The prdoc files', metavar='prdoc', type=str, nargs='*') + args = parser.parse_args() + + if len(args.prdoc) == 0: + print('❌ Need at least one prdoc file as argument.') + exit(1) + + return { 'root': os.path.abspath(args.root[0]), 'prdocs': args.prdoc } + +if __name__ == '__main__': + args = parse_args() + check_prdoc_crate_names(args['root'], args['prdocs']) diff --git a/.github/scripts/check-runtime.py b/.github/scripts/check-runtime.py new file mode 100755 index 000000000000..9f3d047e01f8 --- /dev/null +++ b/.github/scripts/check-runtime.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 + +import json +import sys +import logging +import os + + +def check_constant(spec_pallet_id, spec_pallet_value, meta_constant): + """ + Check a single constant + + :param spec_pallet_id: + :param spec_pallet_value: + :param meta_constant: + :return: + """ + if meta_constant['name'] == list(spec_pallet_value.keys())[0]: + constant = meta_constant['name'] + res = list(spec_pallet_value.values())[0]["value"] == meta_constant["value"] + + logging.debug(f" Checking pallet:{spec_pallet_id}/constants/{constant}") + logging.debug(f" spec_pallet_value: {spec_pallet_value}") + logging.debug(f" meta_constant: {meta_constant}") + logging.info(f"pallet:{spec_pallet_id}/constants/{constant} -> {res}") + return res + else: + # logging.warning(f" Skipping pallet:{spec_pallet_id}/constants/{meta_constant['name']}") + pass + + +def check_pallet(metadata, spec_pallet): + """ + Check one pallet + + :param metadata: + :param spec_pallet_id: + :param spec_pallet_value: + :return: + """ + + spec_pallet_id, spec_pallet_value = spec_pallet + logging.debug(f"Pallet: {spec_pallet_id}") + + metadata_pallets = metadata["pallets"] + metadata_pallet = metadata_pallets[spec_pallet_id] + + res = map(lambda meta_constant_value: check_constant( + spec_pallet_id, spec_pallet_value["constants"], meta_constant_value), + metadata_pallet["constants"].values()) + res = list(filter(lambda item: item is not None, res)) + return all(res) + + +def check_pallets(metadata, specs): + """ + CHeck all pallets + + :param metadata: + :param specs: + :return: + """ + + res = list(map(lambda spec_pallet: check_pallet(metadata, spec_pallet), + specs['pallets'].items())) + res = list(filter(lambda item: item is not None, res)) + return all(res) + + +def check_metadata(metadata, specs): + """ + Check metadata (json) against a list of expectations + + :param metadata: Metadata in JSON format + :param expectation: Expectations + :return: Bool + """ + + res = check_pallets(metadata, specs) + return res + + +def help(): + """ Show some simple help """ + + print(f"You must pass 2 args, you passed {len(sys.argv) - 1}") + print("Sample call:") + print("check-runtime.py ") + + +def load_json(file): + """ Load json from a file """ + + f = open(file) + return json.load(f) + + +def main(): + LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() + logging.basicConfig(level=LOGLEVEL) + + if len(sys.argv) != 3: + help() + exit(1) + + metadata_file = sys.argv[1] + specs_file = sys.argv[2] + print(f"Checking metadata from: {metadata_file} with specs from: {specs_file}") + + metadata = load_json(metadata_file) + specs = load_json(specs_file) + + res = check_metadata(metadata, specs) + + if res: + logging.info(f"OK") + exit(0) + else: + print("") + logging.info(f"Some errors were found, run again with LOGLEVEL=debug") + exit(1) + +if __name__ == "__main__": + main() diff --git a/.github/scripts/check-workspace.py b/.github/scripts/check-workspace.py new file mode 100644 index 000000000000..d5197100ad25 --- /dev/null +++ b/.github/scripts/check-workspace.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 + +# Ensures that: +# - all crates are added to the root workspace +# - local dependencies are resolved via `path` +# +# It does not check that the local paths resolve to the correct crate. This is already done by cargo. +# +# Must be called with a folder containing a `Cargo.toml` workspace file. + +import os +import sys +import toml +import argparse + +def parse_args(): + parser = argparse.ArgumentParser(description='Check Rust workspace integrity.') + + parser.add_argument('workspace_dir', help='The directory to check', metavar='workspace_dir', type=str, nargs=1) + parser.add_argument('--exclude', help='Exclude crate paths from the check', metavar='exclude', type=str, nargs='*', default=[]) + + args = parser.parse_args() + return (args.workspace_dir[0], args.exclude) + +def main(root, exclude): + workspace_crates = get_members(root, exclude) + all_crates = get_crates(root, exclude) + print(f'📦 Found {len(all_crates)} crates in total') + + check_duplicates(workspace_crates) + check_missing(workspace_crates, all_crates) + check_links(all_crates) + +# Extract all members from a workspace. +# Return: list of all workspace paths +def get_members(workspace_dir, exclude): + print(f'🔎 Indexing workspace {os.path.abspath(workspace_dir)}') + + root_manifest_path = os.path.join(workspace_dir, "Cargo.toml") + if not os.path.exists(root_manifest_path): + print(f'❌ No root manifest found at {root_manifest}') + sys.exit(1) + + root_manifest = toml.load(root_manifest_path) + if not 'workspace' in root_manifest: + print(f'❌ No workspace found in root {root_manifest_path}') + sys.exit(1) + + if not 'members' in root_manifest['workspace']: + return [] + + members = [] + for member in root_manifest['workspace']['members']: + if member in exclude: + print(f'❌ Excluded member should not appear in the workspace {member}') + sys.exit(1) + members.append(member) + + return members + +# List all members of the workspace. +# Return: Map name -> (path, manifest) +def get_crates(workspace_dir, exclude_crates) -> dict: + crates = {} + + for root, dirs, files in os.walk(workspace_dir): + if "target" in root: + continue + for file in files: + if file != "Cargo.toml": + continue + + path = os.path.join(root, file) + with open(path, "r") as f: + content = f.read() + manifest = toml.loads(content) + + if 'workspace' in manifest: + if root != workspace_dir: + print("⏩ Excluded recursive workspace at %s" % path) + continue + + # Cut off the root path and the trailing /Cargo.toml. + path = path[len(workspace_dir)+1:-11] + name = manifest['package']['name'] + if path in exclude_crates: + print("⏩ Excluded crate %s at %s" % (name, path)) + continue + crates[name] = (path, manifest) + + return crates + +# Check that there are no duplicate entries in the workspace. +def check_duplicates(workspace_crates): + print(f'🔎 Checking for duplicate crates') + found = {} + for path in workspace_crates: + if path in found: + print(f'❌ crate is listed twice in the workspace {path}') + sys.exit(1) + found[path] = True + +# Check that all crates are in the workspace. +def check_missing(workspace_crates, all_crates): + print(f'🔎 Checking for missing crates') + if len(workspace_crates) == len(all_crates): + print(f'✅ All {len(all_crates)} crates are in the workspace') + return + + missing = [] + # Find out which ones are missing. + for name, (path, manifest) in all_crates.items(): + if not path in workspace_crates: + missing.append([name, path, manifest]) + missing.sort() + + for name, path, _manifest in missing: + print("❌ %s in %s" % (name, path)) + print(f'😱 {len(all_crates) - len(workspace_crates)} crates are missing from the workspace') + sys.exit(1) + +# Check that all local dependencies are good. +def check_links(all_crates): + print(f'🔎 Checking for broken dependency links') + links = [] + broken = [] + + for name, (path, manifest) in all_crates.items(): + def check_deps(deps): + for dep in deps: + # Could be renamed: + dep_name = dep + if 'package' in deps[dep]: + dep_name = deps[dep]['package'] + if dep_name in all_crates: + links.append((name, dep_name)) + + if name == 'polkadot-sdk': + if not 'path' in deps[dep]: + broken.append((name, dep_name, "crate must use path")) + return + elif not 'workspace' in deps[dep] or not deps[dep]['workspace']: + broken.append((name, dep_name, "crate must use workspace inheritance")) + return + + def check_crate(deps): + to_checks = ['dependencies', 'dev-dependencies', 'build-dependencies'] + + for to_check in to_checks: + if to_check in deps: + check_deps(deps[to_check]) + + # There could possibly target dependant deps: + if 'target' in manifest: + # Target dependant deps can only have one level of nesting: + for _, target in manifest['target'].items(): + check_crate(target) + + check_crate(manifest) + + links.sort() + broken.sort() + + if len(broken) > 0: + for (l, r, reason) in broken: + print(f'❌ {l} -> {r} ({reason})') + + print("💥 %d out of %d links are broken" % (len(broken), len(links))) + sys.exit(1) + else: + print("✅ All %d internal dependency links are correct" % len(links)) + +if __name__ == "__main__": + args = parse_args() + main(args[0], args[1]) diff --git a/.github/workflows/gitspiegel-trigger.yml b/.github/workflows/gitspiegel-trigger.yml new file mode 100644 index 000000000000..01058ad74d0b --- /dev/null +++ b/.github/workflows/gitspiegel-trigger.yml @@ -0,0 +1,35 @@ +name: gitspiegel sync + +# This workflow doesn't do anything, it's only use is to trigger "workflow_run" +# webhook, that'll be consumed by gitspiegel +# This way, gitspiegel won't do mirroring, unless this workflow runs, +# and running the workflow is protected by GitHub + +on: + pull_request: + types: + - opened + - synchronize + - unlocked + - ready_for_review + - reopened + # doesn't work as intended, triggers "workflow_run" webhook in any case + # the job doesn't check out any code, so it is relatively safe to run it on any event + # pull_request_target: + # types: + # - opened + # - synchronize + # - unlocked + # - ready_for_review + # - reopened + merge_group: + +# drop all permissions for GITHUB_TOKEN +permissions: {} + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Do nothing + run: echo "let's go" diff --git a/.github/workflows/issues-auto-add-parachain.yml b/.github/workflows/issues-auto-add-parachain.yml new file mode 100644 index 000000000000..6b5222b6ff74 --- /dev/null +++ b/.github/workflows/issues-auto-add-parachain.yml @@ -0,0 +1,30 @@ +# If there are new issues related to the async backing feature, +# add it to the parachain team's board and set a custom "meta" field. + +name: Add selected issues to Parachain team board +on: + issues: + types: + - labeled + +jobs: + add-parachain-issues: + if: github.event.label.name == 'T16-async_backing' + runs-on: ubuntu-latest + steps: + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.PROJECT_APP_ID }} + private_key: ${{ secrets.PROJECT_APP_KEY }} + - name: Sync issues + uses: paritytech/github-issue-sync@v0.3.2 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PROJECT_TOKEN: ${{ steps.generate_token.outputs.token }} + project: 119 # Parachain team board + project_field: 'meta' + project_value: 'async backing' + labels: | + T16-async_backing diff --git a/.github/workflows/issues-auto-label.yml b/.github/workflows/issues-auto-label.yml new file mode 100644 index 000000000000..12ffce702cdc --- /dev/null +++ b/.github/workflows/issues-auto-label.yml @@ -0,0 +1,17 @@ +# If the author of the issues is not a contributor to the project, label +# the issue with 'Z0-unconfirmed' + +name: Label New Issues +on: + issues: + types: [opened] + +jobs: + label-new-issues: + runs-on: ubuntu-latest + steps: + - name: Label drafts + uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4 + if: github.event.issue.author_association == 'NONE' + with: + add-labels: "I10-unconfirmed" diff --git a/.github/workflows/misc-notify-burnin-label.yml b/.github/workflows/misc-notify-burnin-label.yml new file mode 100644 index 000000000000..b630cd07440f --- /dev/null +++ b/.github/workflows/misc-notify-burnin-label.yml @@ -0,0 +1,24 @@ +name: Notify DevOps when burn-in label applied +on: + pull_request: + types: [labeled] + +jobs: + notify-devops: + runs-on: ubuntu-latest + strategy: + matrix: + channel: + - name: 'Team: DevOps' + room: '!lUslSijLMgNcEKcAiE:parity.io' + + steps: + - name: Send Matrix message to ${{ matrix.channel.name }} + if: startsWith(github.event.label.name, 'A0-') + uses: s3krit/matrix-message-action@70ad3fb812ee0e45ff8999d6af11cafad11a6ecf # v0.0.3 + with: + room_id: ${{ matrix.channel.room }} + access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} + server: m.parity.io + message: | + @room Burn-in request received for [${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }}) diff --git a/.github/workflows/misc-review-bot-merge-queue.yml b/.github/workflows/misc-review-bot-merge-queue.yml new file mode 100644 index 000000000000..28b3bc7533c0 --- /dev/null +++ b/.github/workflows/misc-review-bot-merge-queue.yml @@ -0,0 +1,25 @@ +# Actions that makes review-bot green in the merge queue +name: Merge-Queue + +on: + merge_group: + +jobs: + trigger-merge-queue-action: + runs-on: ubuntu-latest + environment: merge-queues + steps: + - name: Generate token + id: app_token + uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0 + with: + app_id: ${{ secrets.REVIEW_APP_ID }} + private_key: ${{ secrets.REVIEW_APP_KEY }} + - name: Add Merge Queue status check + uses: billyjbryant/create-status-check@3e6fa0ac599d10d9588cf9516ca4330ef669b858 # v2 + with: + authToken: ${{ steps.app_token.outputs.token }} + context: "review-bot" + description: "PRs for merge queue gets approved" + state: "success" + sha: ${{ github.event.merge_group.head_commit.id }} diff --git a/.github/workflows/release-99_notif-published.yml b/.github/workflows/release-99_notif-published.yml new file mode 100644 index 000000000000..b5b2ed38e845 --- /dev/null +++ b/.github/workflows/release-99_notif-published.yml @@ -0,0 +1,50 @@ +name: Release - Announce release to Matrix rooms +on: + release: + types: + - published + - prereleased + +jobs: + ping_matrix: + runs-on: ubuntu-latest + environment: release + strategy: + matrix: + channel: + # Internal + - name: "RelEng: Polkadot Release Coordination" + room: '!cqAmzdIcbOFwrdrubV:parity.io' + pre-release: true + + # External + - name: 'Ledger <> Polkadot Coordination' + room: '!EoIhaKfGPmFOBrNSHT:web3.foundation' + pre-release: true + + # Public + - name: '#polkadotvalidatorlounge:web3.foundation' + room: '!NZrbtteFeqYKCUGQtr:matrix.parity.io' + pre-releases: false + - name: '#polkadot-announcements:parity.io' + room: '!UqHPWiCBGZWxrmYBkF:matrix.parity.io' + pre-releases: false + - name: '#kusama-announce:parity.io' + room: '!FMwxpQnYhRCNDRsYGI:matrix.parity.io' + pre-releases: false + + steps: + - name: Matrix notification to ${{ matrix.channel.name }} + if: github.event.release.prerelease == false || matrix.channel.pre-release + uses: s3krit/matrix-message-action@70ad3fb812ee0e45ff8999d6af11cafad11a6ecf # v0.0.3 + with: + room_id: ${{ matrix.channel.room }} + access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} + server: m.parity.io + message: | + @room + + A new node release has been ${{github.event.action}} in **${{github.event.repository.full_name}}:**
+ Release version: [${{github.event.release.tag_name}}](${{github.event.release.html_url}}) + + ----- diff --git a/.github/workflows/review-trigger.yml b/.github/workflows/review-trigger.yml new file mode 100644 index 000000000000..ec4a62afc0c7 --- /dev/null +++ b/.github/workflows/review-trigger.yml @@ -0,0 +1,73 @@ +name: Review-Trigger + +on: + pull_request_target: + types: + - opened + - reopened + - synchronize + - review_requested + - review_request_removed + - ready_for_review + pull_request_review: + +jobs: + trigger-review-bot: + # (It is not a draft) && (it is not a review || it is an approving review) + if: ${{ github.event.pull_request.draft != true && (github.event_name != 'pull_request_review' || (github.event.review && github.event.review.state == 'APPROVED')) }} + runs-on: ubuntu-latest + name: trigger review bot + steps: + - name: Skip merge queue + if: ${{ contains(github.ref, 'gh-readonly-queue') }} + run: exit 0 + - name: Get PR data + id: comments + run: | + echo "bodies=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '[.comments[].body]')" >> "$GITHUB_OUTPUT" + echo "reviews=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews --jq '[.[].state]')" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ github.token }} + - name: Fail when author pushes new code + # Require new reviews when the author is pushing and he is not a member + if: | + contains(fromJson(steps.comments.outputs.reviews), 'APPROVED') && + github.event_name == 'pull_request_target' && + github.event.action == 'synchronize' && + github.event.sender.login == github.event.pull_request.user.login && + github.event.pull_request.author_association != 'CONTRIBUTOR' && + github.event.pull_request.author_association != 'MEMBER' + run: | + echo "User's association is ${{ github.event.pull_request.author_association }}" + # We get the list of reviewers who approved the PR + REVIEWERS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews \ + --jq '{reviewers: [.[] | select(.state == "APPROVED") | .user.login]}') + + # We request them to review again + echo $REVIEWERS | gh api --method POST repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers --input - + + echo "::error::Project needs to be reviewed again" + exit 1 + env: + GH_TOKEN: ${{ github.token }} + - name: Comment requirements + # If the previous step failed and github-actions hasn't commented yet we comment instructions + if: failure() && !contains(fromJson(steps.comments.outputs.bodies), 'Review required! Latest push from author must always be reviewed') + run: | + gh pr comment ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --body "Review required! Latest push from author must always be reviewed" + env: + GH_TOKEN: ${{ github.token }} + COMMENTS: ${{ steps.comments.outputs.users }} + - name: Get PR number + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + echo "Saving PR number: $PR_NUMBER" + mkdir -p ./pr + echo $PR_NUMBER > ./pr/pr_number + - uses: actions/upload-artifact@v4 + name: Save PR number + with: + name: pr_number + path: pr/ + retention-days: 5