From 96d9037347b7eaff716911647e6e4bdd6d71a98c Mon Sep 17 00:00:00 2001 From: Derek Lee Date: Wed, 27 Jul 2022 16:00:39 -0700 Subject: [PATCH] github-actions: Auto-backporting An implementation of semi-automating the backporting process. This implementation has two steps: 1. Checking whether any associated issues are marked as bugs If they do, mark with `auto-backport` label 2. On a successful merge, if there is a `auto-backport` label and there are any tags of `backport-to-BRANCHNAME`, it calls an action that cherry-picks the commits in the PR and automatically creates a PR to those branches. This action uses https://github.com/sqren/backport-github-action Fixes #3618 Signed-off-by: Derek Lee --- .github/workflows/add-backport-label.yaml | 100 ++++++++++++++++++++++ .github/workflows/auto-backport.yaml | 29 +++++++ 2 files changed, 129 insertions(+) create mode 100644 .github/workflows/add-backport-label.yaml create mode 100644 .github/workflows/auto-backport.yaml diff --git a/.github/workflows/add-backport-label.yaml b/.github/workflows/add-backport-label.yaml new file mode 100644 index 0000000000..5774bb8059 --- /dev/null +++ b/.github/workflows/add-backport-label.yaml @@ -0,0 +1,100 @@ +name: Add backport label + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - edited + - labeled + - unlabeled + +jobs: + check-issues: + if: ${{ github.event.label.name != 'auto-backport' }} + runs-on: ubuntu-latest + steps: + - name: Checkout code to allow hub to communicate with the project + if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }} + uses: actions/checkout@v3 + + - name: Install hub extension script + run: | + pushd $(mktemp -d) &>/dev/null + git clone --single-branch --depth 1 "https://github.com/kata-containers/.github" && cd .github/scripts + sudo install hub-util.sh /usr/local/bin + popd &>/dev/null + + - name: Determine whether to add label + if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CONTAINS_AUTO_BACKPORT: ${{ contains(github.event.pull_request.labels.*.name, 'auto-backport') }} + id: add_label + run: | + pr=${{ github.event.pull_request.number }} + linked_issue_urls=$(hub-util.sh \ + list-issues-for-pr "$pr" |\ + grep -v "^\#" |\ + cut -d';' -f3 || true) + [ -z "$linked_issue_urls" ] && { + echo "::error::No linked issues for PR $pr" + exit 1 + } + has_bug=false + for issue_url in $(echo "$linked_issue_urls") + do + issue=$(echo "$issue_url"| awk -F\/ '{print $NF}' || true) + [ -z "$issue" ] && { + echo "::error::Cannot determine issue number from $issue_url for PR $pr" + exit 1 + } + labels=$(hub-util.sh list-labels-for-issue "$issue") + + label_names=$(echo $labels | jq -r '.[].name' || true) + if [[ "$label_names" =~ "bug" ]]; then + has_bug=true + break + fi + done + + has_backport_needed_label=${{ contains(github.event.pull_request.labels.*.name, 'needs-backport') }} + has_no_backport_needed_label=${{ contains(github.event.pull_request.labels.*.name, 'no-backport-needed') }} + + echo "::set-output name=add_backport_label::false" + if [ $has_backport_needed_label = true ] || [ $has_bug = true ]; then + if [[ $has_no_backport_needed_label = false ]]; then + echo "::set-output name=add_backport_label::true" + fi + fi + + # Do not spam comment, only if auto-backport label is going to be newly added. + echo "::set-output name=auto_backport_added::$CONTAINS_AUTO_BACKPORT" + + - name: Add comment + if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') && steps.add_label.outputs.add_backport_label == 'true' && steps.add_label.outputs.auto_backport_added == 'false' }} + uses: actions/github-script@v6 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This issue has been marked for auto-backporting. Add label(s) backport-to-BRANCHNAME to backport to them' + }) + + # Allow label to be removed by adding no-backport-needed label + - name: Remove auto-backport label + if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') && steps.add_label.outputs.add_backport_label == 'false' }} + uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 + with: + remove-labels: "auto-backport" + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Add auto-backport label + if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') && steps.add_label.outputs.add_backport_label == 'true' }} + uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 + with: + add-labels: "auto-backport" + repo-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/auto-backport.yaml b/.github/workflows/auto-backport.yaml new file mode 100644 index 0000000000..6504dc4883 --- /dev/null +++ b/.github/workflows/auto-backport.yaml @@ -0,0 +1,29 @@ +on: + pull_request_target: + types: ["labeled", "closed"] + +jobs: + backport: + name: Backport PR + runs-on: ubuntu-latest + if: | + github.event.pull_request.merged == true + && contains(github.event.pull_request.labels.*.name, 'auto-backport') + && ( + (github.event.action == 'labeled' && github.event.label.name == 'auto-backport') + || (github.event.action == 'closed') + ) + steps: + - name: Backport Action + uses: sqren/backport-github-action@v8.9.2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + auto_backport_label_prefix: backport-to- + + - name: Info log + if: ${{ success() }} + run: cat /home/runner/.backport/backport.info.log + + - name: Debug log + if: ${{ failure() }} + run: cat /home/runner/.backport/backport.debug.log