From dc23b0d18a0d27fb2cbf4df41dee8e707fcbc54f Mon Sep 17 00:00:00 2001 From: Jonas Daniels Date: Thu, 22 Oct 2026 11:37:42 -0700 Subject: [PATCH] ci: pin every GitHub Action to a commit SHA A tag like actions/checkout@v4 points wherever its owner last moved it. A hijacked tag runs in our jobs with our secrets and no diff here, which is how the tj-actions compromise spread. Each `uses:` now names the commit its tag resolved to today, with the tag kept as a comment. Dependabot bumps the pins weekly, a week after each release, so they don't freeze. agent-labs-dev is about to require SHA-pinned actions org-wide, and an unpinned workflow will fail once it does. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 13 +++++++++++++ .github/workflows/ci.yml | 6 +++--- .github/workflows/determinism.yml | 10 +++++----- .github/workflows/pages.yml | 12 ++++++------ .github/workflows/release.yml | 6 +++--- .github/workflows/review-smoke.yml | 6 +++--- 6 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e57a96e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + # Keeps the SHA-pinned actions moving. cooldown waits until a release is a + # week old, since hijacked releases are usually pulled within hours. + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + cooldown: + default-days: 7 + groups: + actions: + patterns: ["*"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4e7c68..b233a64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,11 +12,11 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 # No `version:` here: it is read from package.json's packageManager, # and pinning it twice makes the action refuse to run at all. - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: pnpm diff --git a/.github/workflows/determinism.yml b/.github/workflows/determinism.yml index 57412d3..1994fb0 100644 --- a/.github/workflows/determinism.yml +++ b/.github/workflows/determinism.yml @@ -21,11 +21,11 @@ jobs: flake-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 # No `version:` here: it is read from package.json's packageManager, # and pinning it twice makes the action refuse to run at all. - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: pnpm @@ -42,7 +42,7 @@ jobs: - name: Upload diff artifacts on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: determinism-diffs path: | @@ -56,5 +56,5 @@ jobs: runner-image: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - run: docker build -t bugpatrol-runner:ci -f images/runner/Dockerfile . diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index e4c15c0..87e13c3 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -24,10 +24,10 @@ jobs: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 # No `version:` here: it is read from package.json's packageManager. - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: pnpm @@ -35,9 +35,9 @@ jobs: - run: pnpm --filter @bugpatrol/site build env: SITE_BASE_PATH: /bugpatrol - - uses: actions/configure-pages@v5 - - uses: actions/upload-pages-artifact@v3 + - uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 + - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 with: path: site/out - id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6471198..a3c15f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,12 +25,12 @@ jobs: # itself only allows deployments from main. environment: npm steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: fetch-depth: 0 # packageManager owns the pnpm version; a second pin makes setup fail. - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 registry-url: https://registry.npmjs.org diff --git a/.github/workflows/review-smoke.yml b/.github/workflows/review-smoke.yml index 5ccc76e..f7e3c5f 100644 --- a/.github/workflows/review-smoke.yml +++ b/.github/workflows/review-smoke.yml @@ -46,10 +46,10 @@ jobs: # The explorer alone may use its 20 minutes; the base build and the judge come after. timeout-minutes: 45 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 # No `version:` here: it is read from package.json's packageManager. - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 22 cache: pnpm