From a60894c76e2436bb4e50b7cfbd3c0d25f7f8a4ef Mon Sep 17 00:00:00 2001 From: DJ Date: Thu, 16 Apr 2026 10:53:18 -0700 Subject: [PATCH 1/3] fix(dependabot-rebase): use GITHUB_TOKEN for update-branch, app token for approvals The GitHub App lacks 'workflows' permission, causing update-branch to fail with HTTP 403 when the merge would include .github/workflows/ changes from main. Fix: use GITHUB_TOKEN (which has implicit workflows write permission in push-triggered workflows) for the update-branch call. Reserve the app token for approvals and merges, where the app bot identity matters: - Approvals: attributed to the trusted app bot (satisfies require_last_push_approval since GITHUB_TOKEN was the pusher, not the app) - Merges: attributed to the app bot so the resulting push to main re-triggers this workflow, enabling the self-sustaining serialization chain Also adds contents:write, pull-requests:write, workflows:write permissions to the job so GITHUB_TOKEN can perform these operations. --- .../workflows/dependabot-rebase-reusable.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dependabot-rebase-reusable.yml b/.github/workflows/dependabot-rebase-reusable.yml index 2f6b956..330770a 100644 --- a/.github/workflows/dependabot-rebase-reusable.yml +++ b/.github/workflows/dependabot-rebase-reusable.yml @@ -48,8 +48,9 @@ jobs: update-and-merge: runs-on: ubuntu-latest permissions: - contents: read - pull-requests: read + contents: write # needed for update-branch (may touch .github/workflows/) + pull-requests: write + workflows: write # needed to update branches containing workflow file changes steps: - name: Check app secrets env: @@ -69,7 +70,8 @@ jobs: - name: Update and merge Dependabot PRs env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GITHUB_TOKEN for update-branch (has workflows permission) + APP_TOKEN: ${{ steps.app-token.outputs.token }} # app token reserved for approvals REPO: ${{ github.repository }} run: | # Find open Dependabot PRs @@ -108,7 +110,10 @@ jobs: --json autoMergeRequest --jq '.autoMergeRequest != null') if [[ "$AUTO_MERGE_ENABLED" == "true" ]]; then echo " Re-approving to refresh stale approval" - if gh pr review "$PR_NUMBER" --repo "$REPO" --approve \ + # Use app token for approval so it is attributed to the trusted app identity. + # GITHUB_TOKEN (used above for update-branch) is the pusher, so the + # approver (app) satisfies require_last_push_approval. + if GH_TOKEN="$APP_TOKEN" gh pr review "$PR_NUMBER" --repo "$REPO" --approve \ --body "Re-approved after branch update to keep up-to-date with main." \ --silent; then echo " Re-approved PR #$PR_NUMBER" @@ -170,7 +175,10 @@ jobs: fi echo " All checks pass — merging PR #$PR_NUMBER" - if gh api "repos/$REPO/pulls/$PR_NUMBER/merge" \ + # Use app token for merge so the resulting push to main is attributed to the + # app bot — this triggers the workflow again via push event, enabling the + # self-sustaining chain that serializes Dependabot PR merges one at a time. + if GH_TOKEN="$APP_TOKEN" gh api "repos/$REPO/pulls/$PR_NUMBER/merge" \ -X PUT -f merge_method=squash \ --silent; then echo " Merged PR #$PR_NUMBER" From 87ee15a27a3d1f9959f16dbf751b0c4e195ce8ac Mon Sep 17 00:00:00 2001 From: DJ Date: Thu, 16 Apr 2026 10:55:49 -0700 Subject: [PATCH 2/3] fix: remove invalid 'workflows' job permission scope (not a valid GHA scope) 'workflows' is a GitHub App permission, not a GitHub Actions job permission scope. actionlint correctly rejects it. GITHUB_TOKEN with contents:write in a push-triggered workflow already handles .github/workflows/ file updates. --- .github/workflows/dependabot-rebase-reusable.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dependabot-rebase-reusable.yml b/.github/workflows/dependabot-rebase-reusable.yml index 330770a..3a865f8 100644 --- a/.github/workflows/dependabot-rebase-reusable.yml +++ b/.github/workflows/dependabot-rebase-reusable.yml @@ -50,7 +50,6 @@ jobs: permissions: contents: write # needed for update-branch (may touch .github/workflows/) pull-requests: write - workflows: write # needed to update branches containing workflow file changes steps: - name: Check app secrets env: From a06933c009ba093dc933a3db975df3f536a6cab2 Mon Sep 17 00:00:00 2001 From: DJ Date: Thu, 16 Apr 2026 10:59:00 -0700 Subject: [PATCH 3/3] fix(dependabot-rebase): grant contents:write + pull-requests:write in caller stubs Reusable workflow permissions are capped by the calling job. Update both the live caller (.github/workflows/dependabot-rebase.yml) and the standards template (standards/workflows/dependabot-rebase.yml) to grant write permissions so the reusable's GITHUB_TOKEN can call update-branch and approve PRs. Also update the pinned SHA to origin/main (35e0e20) which includes the re-approval fix from PR #140. --- .github/workflows/dependabot-rebase.yml | 6 +++--- standards/workflows/dependabot-rebase.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dependabot-rebase.yml b/.github/workflows/dependabot-rebase.yml index e049547..4f66a0b 100644 --- a/.github/workflows/dependabot-rebase.yml +++ b/.github/workflows/dependabot-rebase.yml @@ -38,9 +38,9 @@ permissions: {} jobs: dependabot-rebase: permissions: - contents: read - pull-requests: read - uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@ae9709f4466dec60a5733c9e7487f69dcd004e05 # v1 + contents: write # update-branch via GITHUB_TOKEN (may touch .github/workflows/) + pull-requests: write # re-approve PRs after branch update + uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@35e0e20fc0fb3d8f40b0408a85b0eb208213cb1e # v1 secrets: APP_ID: ${{ secrets.APP_ID }} APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/standards/workflows/dependabot-rebase.yml b/standards/workflows/dependabot-rebase.yml index e049547..4f66a0b 100644 --- a/standards/workflows/dependabot-rebase.yml +++ b/standards/workflows/dependabot-rebase.yml @@ -38,9 +38,9 @@ permissions: {} jobs: dependabot-rebase: permissions: - contents: read - pull-requests: read - uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@ae9709f4466dec60a5733c9e7487f69dcd004e05 # v1 + contents: write # update-branch via GITHUB_TOKEN (may touch .github/workflows/) + pull-requests: write # re-approve PRs after branch update + uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@35e0e20fc0fb3d8f40b0408a85b0eb208213cb1e # v1 secrets: APP_ID: ${{ secrets.APP_ID }} APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}