Pin GitHub Actions to commit SHAs and add Dependabot - #910
Merged
Conversation
Version tags are mutable. The tj-actions/changed-files compromise repointed every tag at a commit that dumped runner secrets into build logs; only SHA-pinned consumers were unaffected. publish.yml carries id-token: write for PyPI Trusted Publishing, so an action step in that job can mint an OIDC token and publish a release. pypa/gh-action-pypi-publish stays on release/v1. It is a container action resolved as ghcr.io/pypa/gh-action-pypi-publish:<ref>, and a SHA has no matching GHCR image; the existing comment records that even v1.14.0 lacked a manifest. That comment now says this is the deliberate exception rather than an oversight. The Dependabot config is the half that makes SHA pinning sustainable: it rewrites the SHA and its version comment together, so the workflows track upstream instead of freezing. Grouped monthly to keep it to one pull request. Every pin resolves the tag already in use, so behavior is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 28, 2026
Merged
pypa/gh-action-pypi-publish was the last thing in this job that could not be pinned to a commit SHA: it is a container action resolved as ghcr.io/pypa/gh-action-pypi-publish:<ref>, and a SHA has no matching GHCR image. That mattered because the job runs with id-token: write, so any step in it can mint an OIDC token and publish a release. uv does the trusted-publishing exchange itself and uploads PEP 740 attestations by default, so the release path loses nothing and gains a fully pinned job. uv is already present via setup-uv, which this branch pins. --trusted-publishing always rather than the default automatic: it fails loudly instead of falling back to looking for an API token that does not exist. Verified locally that the invocation reaches the OIDC exchange and stops there for want of a token. verify-metadata: false is moot -- twine check and check_direct_dependencies.py already run against dist/ in the step above. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Version tags are mutable. The
tj-actions/changed-filescompromise in March 2025 repointed every version tag at a commit that dumped runner secrets into build logs, hitting roughly 23,000 repositories; tag pinning offered no protection and SHA pinning offered complete protection.This repository is the highest-value target in the org.
publish.ymlruns withid-token: writefor PyPI Trusted Publishing, so any action step in that job can mint an OIDC token and publish anord-schemarelease. It also publishes to npm and pushes tags withsecrets.ACTIONS_PUSH.No exceptions left
pypa/gh-action-pypi-publishcould not be SHA-pinned — it is a container action resolved asghcr.io/pypa/gh-action-pypi-publish:<ref>, and a commit SHA has no matching GHCR image (the workflow's own comment records that evenv1.14.0had no manifest at publish time). Rather than carry it as a documented exception, #911 replaced it withuv publish --trusted-publishing always, which is now merged into this branch.uv performs the OIDC exchange itself and uploads PEP 740 attestations by default, so the release path lost nothing. Every
uses:in this repository now resolves to a commit SHA, and every step in theid-token: writejob is either a SHA-pinned action or arun:block.Dependabot is the other half
Dependabot understands SHA-pinned actions and rewrites the SHA together with its trailing
# vNcomment, so pinned workflows keep tracking upstream. Without it, pinning freezes the workflows on whatever was current the day they were written.That failure mode is already live in this org: ord-app and ord-infrastructure are fully SHA-pinned with no update mechanism, and both sit on
astral-sh/setup-uvv5.4.2 while this repository runs v7. ord-app'sactions/checkoutpin is stale even within v4. Companion Dependabot PRs for those repositories, and the matching change in ord-data (#264), follow.Updates are grouped so this arrives as one pull request a month rather than one per action.
Every pin resolves the tag that was already in use —
checkout@v7,setup-python@v6,setup-node@v6,setup-go@v6,setup-uv@v7,setup-miniconda@v4— so the pinning commit changes no behavior; the PyPI publisher swap in #911 is the one behavioral change on this branch. Resolved through the git refs API, dereferencing annotated tags to their commits. All pre-commit hooks pass.🤖 Generated with Claude Code
Greptile Summary
Pins GitHub Actions to immutable commit SHAs and modernizes release maintenance.
uv publishusing trusted publishing.Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR D[Dependabot monthly update] --> P[Update pinned action SHAs] P --> W[CI and release workflows] W --> B[Build and validate distributions] B --> U[uv trusted publishing] U --> PYPI[PyPI] B --> NPM[npm] PYPI --> G[Push version bump and tag] NPM --> GReviews (2): Last reviewed commit: "Publish to PyPI with uv instead of a thi..." | Re-trigger Greptile