| # Copyright 2023 The Flutter Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| name: Cherry-pick Labeled PR to Release Branch |
| |
| on: |
| # Safe because we only checkout the trusted 'master' branch from the flutteractionsbot/flutter repository |
| # and run cherry-picks on merged commits from the upstream master branch. It does not execute arbitrary user-controlled code. |
| pull_request_target: # zizmor: ignore[dangerous-triggers] |
| branches: [master] |
| types: [labeled] |
| issues: |
| types: [labeled] |
| |
| permissions: |
| contents: read |
| |
| jobs: |
| cherrypick_not_merged_remove_label: |
| name: cherrypick_not_merged_remove_label |
| runs-on: ubuntu-latest |
| if: | |
| github.event_name == 'pull_request_target' && |
| (github.event.label.name == format('cp{0} beta', ':') || github.event.label.name == format('cp{0} stable', ':')) && |
| (github.event.pull_request.merged == false) |
| steps: |
| - name: Leave Comment and Remove Label |
| run: | |
| gh pr edit ${{ github.event.pull_request.number }} --remove-label "cp: beta" |
| gh pr edit ${{ github.event.pull_request.number }} --remove-label "cp: stable" |
| gh pr comment ${{ github.event.pull_request.number }} -R flutter/flutter -b "Only merged pull requests can be cherrypicked." |
| env: |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| |
| remove_label_from_issues: |
| name: remove_label_from_issues |
| runs-on: ubuntu-latest |
| if: | |
| github.event_name == 'issues' && |
| (github.event.label.name == format('cp{0} beta', ':') || github.event.label.name == format('cp{0} stable', ':')) |
| steps: |
| - name: Remove Label and Leave Comment |
| run: | |
| gh issue edit $ISSUE_NUMBER -R flutter/flutter --remove-label "$LABEL_NAME" |
| gh issue comment $ISSUE_NUMBER -R flutter/flutter -b "Cherry-pick labels should only be applied to merged pull requests." |
| env: |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| LABEL_NAME: ${{ github.event.label.name }} |
| ISSUE_NUMBER: ${{ github.event.issue.number }} |
| |
| cherrypick_to_release: |
| name: cherrypick_to_release |
| runs-on: ubuntu-latest |
| if: | |
| github.event_name == 'pull_request_target' && |
| (github.event.label.name == format('cp{0} beta', ':') || github.event.label.name == format('cp{0} stable', ':')) && |
| (github.event.pull_request.merged == true) |
| steps: |
| - name: Get Release Channel |
| id: get-channel |
| env: |
| LABEL_NAME: ${{ github.event.label.name }} |
| run: echo "channel=$(echo $LABEL_NAME | cut -d ':' -f 2 | xargs)" >> "$GITHUB_OUTPUT" |
| |
| - name: Export Release Candidate Branch |
| id: get-branch |
| env: |
| CHANNEL: ${{ steps.get-channel.outputs.channel }} |
| run: | |
| branch=$(curl -f -s "https://raw.githubusercontent.com/flutter/flutter/$CHANNEL/bin/internal/release-candidate-branch.version" | tr -d '\n') |
| if [ -z "$branch" ]; then |
| echo "Error: Failed to fetch release candidate branch for channel $CHANNEL" >&2 |
| exit 1 |
| fi |
| echo "branch=$branch" >> "$GITHUB_OUTPUT" |
| |
| - name: Checkout Flutter Repo |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 |
| with: |
| repository: flutteractionsbot/flutter |
| path: flutter |
| ref: master |
| token: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| # Checkout all history commits on master branch, so that the cp commit is a known object |
| fetch-depth: 0 |
| persist-credentials: false |
| |
| - name: Configure Git |
| run: | |
| gh auth setup-git |
| git config --global user.name "flutteractionsbot" |
| git config --global user.email "<flutter-actions-bot@google.com>" |
| env: |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| |
| # use same name when checking out branch, since the marketplace action does a hard reset. |
| - name: Attempt CP |
| id: attempt-cp |
| working-directory: ./flutter |
| run: | |
| git remote add upstream https://github.com/flutter/flutter.git |
| git fetch upstream "$RELEASE_BRANCH" |
| git fetch upstream master |
| git checkout -b "cp-${CHANNEL}-${MERGE_COMMIT_SHA}" --track "upstream/$RELEASE_BRANCH" |
| git cherry-pick "$MERGE_COMMIT_SHA" |
| env: |
| CHANNEL: ${{ steps.get-channel.outputs.channel }} |
| RELEASE_BRANCH: ${{ steps.get-branch.outputs.branch }} |
| MERGE_COMMIT_SHA: ${{ github.event.pull_request.merge_commit_sha }} |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| |
| - name: Create PR on CP success |
| if: ${{ steps.attempt-cp.conclusion == 'success' }} |
| working-directory: ./flutter |
| id: create-pr |
| run: | |
| git push origin "cp-${CHANNEL}-${MERGE_COMMIT_SHA}" |
| pr_url=$(gh pr create --title "[CP-${CHANNEL}]${PR_TITLE}" --body-file ".github/PR_TEMPLATE/PULL_REQUEST_CP_TEMPLATE.md" --base "${RELEASE_BRANCH}" --label "cp: review" --repo flutter/flutter --head "flutteractionsbot:cp-${CHANNEL}-${MERGE_COMMIT_SHA}") |
| echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT" |
| env: |
| CHANNEL: ${{ steps.get-channel.outputs.channel }} |
| RELEASE_BRANCH: ${{ steps.get-branch.outputs.branch }} |
| MERGE_COMMIT_SHA: ${{ github.event.pull_request.merge_commit_sha }} |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| PR_TITLE: ${{ github.event.pull_request.title }} |
| |
| - name: Leave Comment on CP success |
| if: ${{ steps.create-pr.conclusion == 'success' }} |
| run: | |
| echo "$PR_URL" |
| NEW_PR_NUMBER="${PR_URL##*/}" |
| SUCCESS_MSG=" @$ACTOR please fill out the PR description above, afterwards the release team will review this request." |
| gh pr comment "$NEW_PR_NUMBER" -R flutter/flutter -b "${SUCCESS_MSG}" |
| env: |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |
| ACTOR: ${{ github.actor }} |
| PR_URL: ${{ steps.create-pr.outputs.pr_url }} |
| |
| - name: Leave Comment on CP failure |
| if: ${{ failure() && steps.attempt-cp.conclusion == 'failure' }} |
| run: | |
| FAILURE_MSG="Failed to create CP due to merge conflicts.<br>" |
| FAILURE_MSG+="You will need to create the PR manually. See [the cherrypick wiki](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md) for more info." |
| gh pr comment ${{ github.event.pull_request.number }} -R flutter/flutter -b "${FAILURE_MSG}" |
| env: |
| GH_TOKEN: ${{ secrets.FLUTTERACTIONSBOT_CP_TOKEN }} |