From 628bdd90012bdd58b894b4d0f811c7bd899c3cae Mon Sep 17 00:00:00 2001 From: Egor_P <egor@parity.io> Date: Thu, 20 Mar 2025 12:50:34 +0100 Subject: [PATCH] [CI/CD] Refactor backports flow so that it can determine automatically where to do a backport based on labels (#7976) This PR changes the command-backport.yml flow so that the branch names are not hardcoded in the pipeline file but will be parsed from the labels. The idea is that there are going to be a label representing each stable branch: - A4-backport-stable2407 - A4-backport-stable2409 - A4-backport-stable2412 - A4-backport-stable2503 If the backport is needed to any of those branches or to all of them, the corresponding label can be set on the PR and the branch name will be parsed from it. The labels need to be created in the repo and adjusted as soon as there is a new release appears or an old one disappears. --- .github/scripts/common/lib.sh | 20 ++++++++++ .github/workflows/command-backport.yml | 53 +++++++++++++++++++++----- docs/BACKPORT.md | 6 ++- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/.github/scripts/common/lib.sh b/.github/scripts/common/lib.sh index 11436f8f33a..97530bfdc90 100755 --- a/.github/scripts/common/lib.sh +++ b/.github/scripts/common/lib.sh @@ -508,6 +508,7 @@ validate_stable_tag() { } # Prepare docker stable tag form the polkadot stable tag +# # input: tag (polkaodot-stableYYMM(-X) or polkadot-stableYYMM(-X)-rcX) # output: stableYYMM(-X) or stableYYMM(-X)-rcX prepare_docker_stable_tag() { @@ -519,3 +520,22 @@ prepare_docker_stable_tag() { exit 1 fi } + +# Parse names of the branches from the github labels based on the pattern +# +# input: labels (array of lables like ("A3-backport" "RO-silent" "A4-backport-stable2407" "A4-backport-stable2503")) +# output: BRANCHES (array of the branch names) +parse_branch_names_from_backport_labels() { + labels="$1" + BRANCHES="" + + for label in $labels; do + if [[ "$label" =~ ^A4-backport-stable[0-9]{4}$ ]]; then + branch_name=$(sed 's/A4-backport-//' <<< "$label") + BRANCHES+=" ${branch_name}" + fi + done + + BRANCHES=$(echo "$BRANCHES" | sed 's/^ *//') + echo "$BRANCHES" +} diff --git a/.github/workflows/command-backport.yml b/.github/workflows/command-backport.yml index 67de5418434..2df80bc54a1 100644 --- a/.github/workflows/command-backport.yml +++ b/.github/workflows/command-backport.yml @@ -13,9 +13,13 @@ permissions: actions: write # It may have to backport changes to the CI as well. jobs: - backport: - name: Backport pull request + check-labels: runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ github.token }} + outputs: + LABELS: ${{ steps.check_labels.outputs.LABELS}} + found: ${{ steps.check_labels.outputs.found}} # The 'github.event.pull_request.merged' ensures that it got into master: if: > @@ -23,24 +27,54 @@ jobs: ( github.event_name == 'pull_request_target' && github.event.pull_request.merged && - github.event.pull_request.base.ref == 'master' && - contains(github.event.pull_request.labels.*.name, 'A4-needs-backport') + github.event.pull_request.base.ref == 'master' ) steps: - uses: actions/checkout@v4 + - name: Check for backport labels + id: check_labels + run: | + LABELS=$(gh pr view ${{ github.event.pull_request.number }} --json labels --jq '.labels[].name') + + if echo "$LABELS" | grep -q '^A4-backport-stable'; then + echo "found=true" >> $GITHUB_OUTPUT + readarray -t labels_array <<< "$LABELS" + echo "LABELS=${labels_array[@]}" >> $GITHUB_OUTPUT + else + echo "found=false" >> $GITHUB_OUTPUT + fi + + + backport: + name: Backport pull request + runs-on: ubuntu-latest + needs: [ check-labels ] + if: ${{ needs.check-labels.outputs.found == 'true' }} + steps: + - uses: actions/checkout@v4 + + - name: Get branches to backport to + id: branches + run: | + . ./.github/scripts/common/lib.sh + + LABELS="${{ needs.check-labels.outputs.LABELS }}" + BACKPORT_BRANCHES=$(parse_branch_names_from_backport_labels "$LABELS") + echo "BACKPORT_BRANCHES=${BACKPORT_BRANCHES}" >> $GITHUB_OUTPUT + - name: Generate token id: generate_token uses: actions/create-github-app-token@v1 with: - app_id: ${{ secrets.RELEASE_BACKPORT_AUTOMATION_APP_ID }} - private_key: ${{ secrets.RELEASE_BACKPORT_AUTOMATION_APP_PRIVATE_KEY }} + app-id: ${{ secrets.RELEASE_BACKPORT_AUTOMATION_APP_ID }} + private-key: ${{ secrets.RELEASE_BACKPORT_AUTOMATION_APP_PRIVATE_KEY }} - name: Create backport pull requests uses: korthout/backport-action@v3 id: backport with: - target_branches: stable2407 stable2409 stable2412 stable2503 + target_branches: ${{ steps.branches.outputs.BACKPORT_BRANCHES }} merge_commits: skip github_token: ${{ steps.generate_token.outputs.token }} pull_description: | @@ -59,6 +93,7 @@ jobs: "conflict_resolution": "draft_commit_conflicts" } copy_assignees: true + label_pattern: ^A4-backport-stable - name: Label Backports if: ${{ steps.backport.outputs.created_pull_numbers != '' }} @@ -86,11 +121,11 @@ jobs: const reviewer = '${{ github.event.pull_request.user.login }}'; for (const pullNumber of pullNumbers) { - await github.pulls.requestReviewers({ + await github.rest.pulls.requestReviewers({ owner: context.repo.owner, repo: context.repo.repo, pull_number: parseInt(pullNumber), - reviewers: [ reviewer ] + reviewers: [reviewer] }); console.log(`Requested review from ${reviewer} for PR #${pullNumber}`); } diff --git a/docs/BACKPORT.md b/docs/BACKPORT.md index 0b4a97e6f66..50de5a9b34a 100644 --- a/docs/BACKPORT.md +++ b/docs/BACKPORT.md @@ -6,7 +6,11 @@ Backports should only be used to fix bugs or security issues - never to introduc ## Steps 1. Fix a bug through a PR that targets `master`. -2. Add label `A4-needs-backport` to the PR. +2. Add label related to the branch to wich to backport changes to the PR. + - `A4-backport-stable2407` + - `A4-backport-stable2409` + - `A4-backport-stable2412` + - `A4-backport-stable2503` 3. Merge the PR into `master`. 4. Wait for the bot to open the backport PR. 5. Ensure the change is audited or does not need audit. -- GitLab