Repository navigation
Conversation
Add .github/workflows/actions.lock, generated by `gh actions-lock`, which records the commit SHA each action reference resolves to, and pin every workflow's action references to the exact release the lock records instead of a floating major tag. See https://hugovk.dev/blog/2026/lock-github-actions/ Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move every action off node20 to its first node24 major: checkout v5, upload-artifact v6, setup-uv v7, github-script v8, setup-node v5; actions.lock regenerated to match. A `lockfile` job in lint.yml runs `gh actions-lock --verify`, so a `uses:` edit without a regenerated lock, or a locked commit that no longer verifies upstream, fails CI. Dependabot proposes action bumps weekly as one grouped PR, after a seven-day cooldown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gh actions-lock has no cooldown and pins the newest matching release, which put claude-code-action at v1.0.271, two days old. Pin v1.0.268 instead, the newest past the seven days Dependabot waits. Note beside the gh-actions-lock --pin that Dependabot cannot bump it, and record the lock workflow in CLAUDE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aboucaud
marked this pull request as ready for review
November 12, 2026 11:58
- Bump pypa/gh-action-pypi-publish to v1.14.3 for GHSA-5xjx-3w67-w9x9 (a revoked CA in Sigstore's chain breaks Trusted Publishing). - Build releases without the uv cache, which runs on main could have filled. - Set persist-credentials: false on every checkout; nothing pushes, and eval's agent could otherwise read the token from .git/config. - Give lint.yml and tests.yml an explicit read-only token instead of the repository default. - Mark dco.yml's and claude.yml's privileged triggers as reviewed: no checkout of PR code, no expression interpolation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
✅ Eval
lc statusConfusion & pain points (Claude analysis)Confusion & pain points
Full trace: |
ubuntu-latest moved to Ubuntu 26.04, whose Docker 29 defaults to the containerd image store. There lc cannot find its images by config digest, so the Docker smoke tests fail. That is a real bug, tracked in #270; pin the runner so this PR's CI reports on its own changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Renovate regenerates actions.lock itself when it bumps an action, and a custom regex manager also bumps the gh-actions-lock extension lint.yml pins, which Dependabot could not see. Same policy as before: weekly, grouped, seven-day minimum release age. Only `uses:` references are updated; versions passed to setup actions and runner labels are not, since tests.yml's uv is the scaffold floor and its runner is pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Our workflows referenced actions by major tag (
actions/checkout@v4). A tag is a pointer the action's owner, or anyone who compromises their account, can move to arbitrary code, and the next CI run executes it with our secrets in reach. GitHub's answer is the workflow lockfile:gh actions-lockresolves every action, transitive ones included, to a commit SHA and records it in.github/workflows/actions.lock; the runner then rejects any action whose code no longer matches. Workflows stay readable (exact release tags, no SHAs inline), and every dependency change shows up as a reviewable diff. See https://hugovk.dev/blog/2026/lock-github-actions/ and GitHub's docs.A lock is only useful if it stays in sync and stays current, so this PR also verifies it in CI and hands version bumps to Renovate, which regenerates
actions.lockitself when it bumps an action. Both bumps and manual pins wait out a seven-day cooldown, because a compromised or broken release is usually caught and pulled within days. While touching everyuses:, it also moves off node20, whose deprecation warnings every run currently prints, and fixes what zizmor reports on the workflows.Summary
.github/workflows/actions.lock, generated bygh actions-lock; workflows reference exact release tags, the lock carries the SHAs.checkoutv5,upload-artifactv6,setup-uvv7,github-scriptv8,setup-nodev5.claude-code-actionis composite and stays on v1, pinned to v1.0.268 (v1.0.271 was two days old).pypi-publish.yamlwas already on node24 and is unchanged.lockfilejob inlint.ymlrunsgh actions-lock --verify(after GitHub's ownverify-lockfile.yml), so an editeduses:without a regenerated lock fails CI. Its--pin v0.4.1of the extension is tracked by a Renovate custom regex manager..github/renovate.json5: weekly updates ofuses:references and the extension pin, grouped (majors separately), with a 7-dayminimumReleaseAge. Versions passed to setup actions (tests.yml's uv floor, Node) and runner labels are left alone. Validated withrenovate-config-validator --strict, and dry-run locally (--platform=local --dry-run=lookup): it finds every action and the extension pin, and skips the uv floor, Node and runners.CLAUDE.mdrecords the workflow: rungh actions-lockafter anyuses:edit, and hand-pin only releases at least seven days old (gh actions-lockhas no cooldown of its own).pypa/gh-action-pypi-publishv1.14.2 → v1.14.3 for GHSA-5xjx-3w67-w9x9 (critical: a revoked CA in Sigstore's chain breaks Trusted Publishing).maincould have filled (cache-poisoning).persist-credentials: falseon every checkout (artipacked): nothing pushes, and eval's agent could otherwise read the token from.git/config.lint.ymlandtests.ymlget an explicitcontents: readtoken instead of the repository default (excessive-permissions).dco.yml'spull_request_target/issue_commentandclaude.yml'sissue_commentare markedzizmor: ignore[dangerous-triggers]: neither checks out PR code or interpolates untrusted input.Test plan
gh actions-lock --verifypasses locallyzizmor .github/(1.32.0, online audits): no findings, 3 ignoredactions.lock(thelockfilejob checks it)🤖 Generated with Claude Code