From 20977812d0fa3b1862880a115caaeb96edcfd1d1 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 27 Jul 2026 13:06:51 -0700 Subject: [PATCH 1/3] ci: sync Dependabot action pin comments via reusable workflow Thin caller for basecamp/.github's dependabot-sync-actions-comments reusable workflow (basecamp/.github#8): after CI completes on a Dependabot github_actions branch, trusted default-branch code fixes any stale pin version comments and pushes back behind a compare-and-swap lease, using the write deploy key scoped to this repo's dependabot-sync environment (deployment branches: default branch only). --- .../dependabot-sync-actions-comments.yml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/dependabot-sync-actions-comments.yml diff --git a/.github/workflows/dependabot-sync-actions-comments.yml b/.github/workflows/dependabot-sync-actions-comments.yml new file mode 100644 index 00000000..2745075e --- /dev/null +++ b/.github/workflows/dependabot-sync-actions-comments.yml @@ -0,0 +1,46 @@ +name: Sync Dependabot action pin comments + +# Thin caller: all logic lives in basecamp/.github's reusable workflow — +# trusted default-branch code that fetches the Dependabot head branch as data +# only, rewrites stale `# vX.Y.Z` pin comments, and pushes back behind a +# compare-and-swap lease using the write deploy key scoped to this repo's +# dependabot-sync environment. + +on: + workflow_run: # zizmor: ignore[dangerous-triggers] -- only the SHA-pinned reusable workflow (reviewed default-branch code) executes; the Dependabot head branch is fetched as data, never executed + workflows: [Test] + types: [completed] + workflow_dispatch: + inputs: + branch: + description: Dependabot branch to sync (dependabot/github_actions/...) + required: true + type: string + e2e: + description: "E2E proof mode: expect a draft PR authored by the dispatcher on a dependabot/github_actions/e2e-proof-* branch" + required: false + default: false + type: boolean + +permissions: {} + +jobs: + sync: + # Cheap prefilter to avoid a skipped-run entry on every CI completion; + # the reusable workflow re-checks this and everything else. + if: >- + github.event_name == 'workflow_dispatch' || + startsWith(github.event.workflow_run.head_branch, 'dependabot/github_actions/') + uses: basecamp/.github/.github/workflows/dependabot-sync-actions-comments.yml@95a9f7a2bd69c73cd2839eb4a27616e1651497e2 + with: + ci-workflow-name: Test + branch: ${{ inputs.branch || '' }} + e2e: ${{ inputs.e2e || false }} + permissions: + contents: read + actions: write + pull-requests: read + # The deploy key is scoped to this repo's dependabot-sync environment + # (deployment branches: default branch only); environment secrets cannot + # be forwarded explicitly to a reusable workflow, so inherit is required. + secrets: inherit # zizmor: ignore[secrets-inherit] -- see above; the called workflow is SHA-pinned and reads only SYNC_ACTIONS_DEPLOY_KEY, gated by the dependabot-sync environment From 6e2f65641b19eaca5b6faf0966e8f15d88391af1 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 27 Jul 2026 13:06:51 -0700 Subject: [PATCH 2/3] chore(actions): sync action pin comments One-time catch-up applying what the new sync workflow will maintain automatically: version comments on SHA-pinned uses lines whose trailing zizmor annotations prevented Dependabot from rewriting them. --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 17c9ca7c..1331b22b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: persist-credentials: false - name: Set up Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.4.0 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to the cache used by tag-push workflows + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to the cache used by tag-push workflows with: go-version-file: 'go.mod' @@ -46,7 +46,7 @@ jobs: - name: Cache BATS id: cache-bats - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5.0.5 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to the cache used by tag-push workflows + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to the cache used by tag-push workflows with: path: ~/.local key: bats-1.11.0-home @@ -127,7 +127,7 @@ jobs: permission-contents: write - name: Set up Go - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.4.0 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to the cache used by tag-push workflows + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 # zizmor: ignore[cache-poisoning] -- cache is branch-isolated; fork PRs cannot write to the cache used by tag-push workflows with: go-version-file: 'go.mod' From 4238cf9a005cf9163a703e7d5fe843b867214700 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 27 Jul 2026 13:19:04 -0700 Subject: [PATCH 3/3] ci: filter workflow_run to dependabot branches at the trigger Review feedback: the job-level if only skips the job after the run is created; a trigger-level branches filter stops runs from being created for non-Dependabot branches at all. The if stays as defense-in-depth. --- .github/workflows/dependabot-sync-actions-comments.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependabot-sync-actions-comments.yml b/.github/workflows/dependabot-sync-actions-comments.yml index 2745075e..e5c8b612 100644 --- a/.github/workflows/dependabot-sync-actions-comments.yml +++ b/.github/workflows/dependabot-sync-actions-comments.yml @@ -10,6 +10,7 @@ on: workflow_run: # zizmor: ignore[dangerous-triggers] -- only the SHA-pinned reusable workflow (reviewed default-branch code) executes; the Dependabot head branch is fetched as data, never executed workflows: [Test] types: [completed] + branches: ["dependabot/github_actions/**"] workflow_dispatch: inputs: branch: @@ -26,8 +27,9 @@ permissions: {} jobs: sync: - # Cheap prefilter to avoid a skipped-run entry on every CI completion; - # the reusable workflow re-checks this and everything else. + # Defense-in-depth behind the trigger-level branches filter (which stops + # runs from being created for other branches at all); the reusable + # workflow re-checks this and everything else. if: >- github.event_name == 'workflow_dispatch' || startsWith(github.event.workflow_run.head_branch, 'dependabot/github_actions/')