From 75c85cb5f0ca3baae7eb08cbe80e0b5adc7f0236 Mon Sep 17 00:00:00 2001 From: "John \"codefu\" McDole" Date: Fri, 10 Jul 2026 14:36:21 -0700 Subject: [PATCH 1/2] fix(ci): harden some workflows in packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes #189098 ``` ~/.local/bin/zizmor --gh-token=$(gh auth token) .github/workflow INFO zizmor: 🌈 zizmor v1.25.2 INFO audit: zizmor: 🌈 completed .github/workflows/batch_release_pr.yml INFO audit: zizmor: 🌈 completed .github/workflows/go_router_batch.yml INFO audit: zizmor: 🌈 completed .github/workflows/internals/install_flutter/action.yml INFO audit: zizmor: 🌈 completed .github/workflows/pull_request_label.yml INFO audit: zizmor: 🌈 completed .github/workflows/release.yml INFO audit: zizmor: 🌈 completed .github/workflows/release_from_branches.yml INFO audit: zizmor: 🌈 completed .github/workflows/remove_cicd.yml INFO audit: zizmor: 🌈 completed .github/workflows/reusable_release.yml INFO audit: zizmor: 🌈 completed .github/workflows/sync_release_pr.yml No findings to report. Good job! (2 ignored, 56 suppressed) ``` --- .github/workflows/batch_release_pr.yml | 15 ++++++++++----- .../internals/install_flutter/action.yml | 8 ++++++-- .github/workflows/release.yml | 1 + .github/workflows/release_from_branches.yml | 5 ++++- .github/workflows/remove_cicd.yml | 8 ++++++-- .github/workflows/reusable_release.yml | 8 ++++++++ .github/workflows/sync_release_pr.yml | 11 ++++++----- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/.github/workflows/batch_release_pr.yml b/.github/workflows/batch_release_pr.yml index 66fc5b2dc60d..8d808fa75056 100644 --- a/.github/workflows/batch_release_pr.yml +++ b/.github/workflows/batch_release_pr.yml @@ -22,6 +22,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: token: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} + persist-credentials: false - name: "Install Flutter" uses: ./.github/workflows/internals/install_flutter - name: Set up tools @@ -62,13 +63,17 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: ref: ${{ env.HEAD_BRANCH_NAME }} + persist-credentials: false - name: Create batch release PR run: | gh pr create \ - --base "${{ needs.create_batch_release_branch.outputs.release_branch }}" \ - --head "${{ env.HEAD_BRANCH_NAME }}" \ - --title "[${{ github.event.client_payload.package }}] Batch release" \ - --body "This PR was created automatically to batch release the \`${{ github.event.client_payload.package }}\`." \ - --label "override: skip-batch-release-repo-check-${{ github.event.client_payload.package }}" + --base "${NEEDS_CREATE_BATCH_RELEASE_BRANCH_OUTPUTS_RELEASE_BRANCH}" \ + --head "${HEAD_BRANCH_NAME}" \ + --title "[${GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE}] Batch release" \ + --body "This PR was created automatically to batch release the \`${GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE}\`." \ + --label "override: skip-batch-release-repo-check-${GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE}" + env: + NEEDS_CREATE_BATCH_RELEASE_BRANCH_OUTPUTS_RELEASE_BRANCH: ${{ needs.create_batch_release_branch.outputs.release_branch }} + GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE: ${{ github.event.client_payload.package }} diff --git a/.github/workflows/internals/install_flutter/action.yml b/.github/workflows/internals/install_flutter/action.yml index ae1216971b29..a52bf2a1dce3 100644 --- a/.github/workflows/internals/install_flutter/action.yml +++ b/.github/workflows/internals/install_flutter/action.yml @@ -3,7 +3,7 @@ description: "Installs a pinned version of Flutter" runs: using: "composite" steps: - - name: "Install Flutter" + - name: "Clone Flutter" # This uses a pinned version of Flutter rather than `stable` so that it is # not subject to out-of-band failures when new releases happen. It does # not use the auto-rolled pin because there's no way for the autoroller @@ -16,5 +16,9 @@ runs: run: | cd $HOME git clone https://github.com/flutter/flutter.git --depth 1 -b 3.44.0 _flutter - echo "$HOME/_flutter/bin" >> $GITHUB_PATH cd $GITHUB_WORKSPACE + + # GITHUB_PATH write is safe here as it only appends a hardcoded, trusted path ($HOME/_flutter/bin) with no user-controlled input. + - name: "Add Flutter to Path" + shell: bash + run: echo "$HOME/_flutter/bin" >> $GITHUB_PATH # zizmor: ignore[github-env] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 76a9b420e47a..926ee57d97b2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: fetch-depth: 0 # Fetch all history so the tool can get all the tags to determine version. + persist-credentials: false - name: "Install Flutter" uses: ./.github/workflows/internals/install_flutter - name: Set up tools diff --git a/.github/workflows/release_from_branches.yml b/.github/workflows/release_from_branches.yml index 11bd07fbb121..20d6fee14ad4 100644 --- a/.github/workflows/release_from_branches.yml +++ b/.github/workflows/release_from_branches.yml @@ -12,4 +12,7 @@ jobs: with: is-batch-release: true branch-name: '${{ github.ref_name }}' - secrets: inherit + secrets: + USER_NAME: ${{ secrets.USER_NAME }} + USER_EMAIL: ${{ secrets.USER_EMAIL }} + PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }} diff --git a/.github/workflows/remove_cicd.yml b/.github/workflows/remove_cicd.yml index 6f5ff9d0596f..294bbd35a2fd 100644 --- a/.github/workflows/remove_cicd.yml +++ b/.github/workflows/remove_cicd.yml @@ -5,6 +5,8 @@ name: Remove outdated CICD Label on: + # This pull_request_target trigger is safe because the workflow does not checkout any untrusted code or execute code from the PR. + # zizmor: ignore[dangerous-triggers] pull_request_target: types: [synchronize] @@ -21,7 +23,7 @@ jobs: id: check_timing run: | # Get push time (commit date of the head SHA) - PUSH_TIME='${{ github.event.pull_request.updated_at }}' + PUSH_TIME='${GITHUB_EVENT_PULL_REQUEST_UPDATED_AT}' echo "Push time: $PUSH_TIME" # Get latest CICD labeling event time from the last 100 events @@ -39,7 +41,7 @@ jobs: } } } - }' -f owner=${{ github.repository_owner }} -f repo=${{ github.event.repository.name }} -F pr=${{ github.event.pull_request.number }} \ + }' -f owner=${{ github.repository_owner }} -f repo=${GITHUB_EVENT_REPOSITORY_NAME} -F pr=${{ github.event.pull_request.number }} \ --jq '.data.repository.pullRequest.timelineItems.nodes | map(select(.label.name == "CICD")) | last | .createdAt') echo "Label time: $LABEL_TIME" @@ -56,6 +58,8 @@ jobs: fi env: GITHUB_TOKEN: ${{ github.token }} + GITHUB_EVENT_PULL_REQUEST_UPDATED_AT: ${{ github.event.pull_request.updated_at }} + GITHUB_EVENT_REPOSITORY_NAME: ${{ github.event.repository.name }} - name: Remove outdated CICD label if: steps.check_timing.outputs.should_remove == 'true' diff --git a/.github/workflows/reusable_release.yml b/.github/workflows/reusable_release.yml index f3671e6b0cbb..581ca4d1c79a 100644 --- a/.github/workflows/reusable_release.yml +++ b/.github/workflows/reusable_release.yml @@ -8,6 +8,13 @@ on: branch-name: required: true type: string + secrets: + USER_NAME: + required: true + USER_EMAIL: + required: true + PUB_CREDENTIALS: + required: true jobs: release: if: github.repository_owner == 'flutter' @@ -23,6 +30,7 @@ jobs: with: fetch-depth: 0 # Fetch all history so the tool can get all the tags to determine version. ref: ${{ inputs.branch-name }} + persist-credentials: false - name: "Install Flutter" uses: ./.github/workflows/internals/install_flutter - name: Set up tools diff --git a/.github/workflows/sync_release_pr.yml b/.github/workflows/sync_release_pr.yml index 406398542205..bbf2b222570e 100644 --- a/.github/workflows/sync_release_pr.yml +++ b/.github/workflows/sync_release_pr.yml @@ -18,6 +18,7 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: fetch-depth: 0 # Fetch history to allow branch comparison + persist-credentials: false - name: Create Pull Request env: @@ -31,19 +32,19 @@ jobs: COMMITS_COUNT=$(git rev-list --count origin/main..HEAD) if [ "$COMMITS_COUNT" -eq "0" ]; then - echo "No new commits found on ${{ github.ref_name }} compared to main. Nothing to sync." + echo "No new commits found on ${GITHUB_REF_NAME} compared to main. Nothing to sync." exit 0 fi # 3. Extract package name for label - BRANCH_NAME="${{ github.ref_name }}" + BRANCH_NAME="${GITHUB_REF_NAME}" TEMP="${BRANCH_NAME#release-}" PACKAGE_NAME="${TEMP%-*}" # 4. Create the PR directly gh pr create \ --base "main" \ - --head "${{ github.ref_name }}" \ - --title "Sync ${{ github.ref_name }} to main" \ - --body "This automated PR syncs the changes from the release branch ${{ github.ref_name }} back to the main branch." \ + --head "${GITHUB_REF_NAME}" \ + --title "Sync ${GITHUB_REF_NAME} to main" \ + --body "This automated PR syncs the changes from the release branch ${GITHUB_REF_NAME} back to the main branch." \ --label "override: skip-batch-release-repo-check-${PACKAGE_NAME}" From f23c14b27d9d2f11f75b99f51abc4ca5bfdb2928 Mon Sep 17 00:00:00 2001 From: John McDole Date: Fri, 10 Jul 2026 15:14:46 -0700 Subject: [PATCH 2/2] GH_TOKEN and auth. --- .github/workflows/batch_release_pr.yml | 7 +++---- .github/workflows/release.yml | 5 ++++- .github/workflows/reusable_release.yml | 6 +++++- .github/workflows/sync_release_pr.yml | 3 ++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/batch_release_pr.yml b/.github/workflows/batch_release_pr.yml index 8d808fa75056..4fb1eb19af53 100644 --- a/.github/workflows/batch_release_pr.yml +++ b/.github/workflows/batch_release_pr.yml @@ -15,8 +15,6 @@ jobs: outputs: head_branch_created: ${{ steps.check-branch-exists.outputs.exists }} release_branch: ${{ steps.create-branch.outputs.release_branch }} # e.g. release-go_router-17.2.2, returned by branches-for-batch-release tool. - env: - GITHUB_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} steps: - name: checkout repository uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 @@ -34,11 +32,13 @@ jobs: - name: create batch release branch id: create-branch run: | + gh auth setup-git git config --global user.name "flutteractionsbot" git config --global user.email "fluttergithubbot@gmail.com" dart ./script/tool/lib/src/main.dart branches-for-batch-release --packages=${GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE} --branch=${HEAD_BRANCH_NAME} --remote=origin env: GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE: ${{ github.event.client_payload.package }} + GH_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} - name: Check if branch was created id: check-branch-exists run: | @@ -56,8 +56,6 @@ jobs: # The create-pull-request action needs both content and pull-requests permissions. pull-requests: write contents: write - env: - GITHUB_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} steps: - name: checkout repository uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 @@ -75,5 +73,6 @@ jobs: env: NEEDS_CREATE_BATCH_RELEASE_BRANCH_OUTPUTS_RELEASE_BRANCH: ${{ needs.create_batch_release_branch.outputs.release_branch }} GITHUB_EVENT_CLIENT_PAYLOAD_PACKAGE: ${{ github.event.client_payload.package }} + GH_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 926ee57d97b2..775c09ad5fd8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,7 +65,10 @@ jobs: - name: run release run: | + gh auth setup-git git config --global user.name ${{ secrets.USER_NAME }} git config --global user.email ${{ secrets.USER_EMAIL }} dart ./script/tool/lib/src/main.dart publish --all-changed --base-sha=HEAD~ --skip-confirmation --remote=origin - env: {PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}"} + env: + PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/reusable_release.yml b/.github/workflows/reusable_release.yml index 581ca4d1c79a..0435c92e289e 100644 --- a/.github/workflows/reusable_release.yml +++ b/.github/workflows/reusable_release.yml @@ -76,6 +76,7 @@ jobs: - name: run release run: | + gh auth setup-git git config --global user.name "${{ secrets.USER_NAME }}" git config --global user.email "${{ secrets.USER_EMAIL }}" @@ -91,4 +92,7 @@ jobs: --base-sha=HEAD~ \ --skip-confirmation \ --remote=origin - env: { PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}", INPUTS_BRANCH_NAME: "${{ inputs.branch-name }}" } + env: + PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}" + INPUTS_BRANCH_NAME: "${{ inputs.branch-name }}" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sync_release_pr.yml b/.github/workflows/sync_release_pr.yml index bbf2b222570e..e6c7f687ee8b 100644 --- a/.github/workflows/sync_release_pr.yml +++ b/.github/workflows/sync_release_pr.yml @@ -22,8 +22,9 @@ jobs: - name: Create Pull Request env: - GITHUB_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} + GH_TOKEN: ${{ secrets.FLUTTERGITHUBBOT_TOKEN }} run: | + gh auth setup-git # 1. Fetch main so the runner can see the difference git fetch origin main