github_actions: integrate gh-actions-lock lockfile relocking - #15267
Merged
AbhishekBhaskar merged 32 commits intoJul 29, 2026
Merged
github_actions: integrate gh-actions-lock lockfile relocking#15267AbhishekBhaskar merged 32 commits into
AbhishekBhaskar merged 32 commits into
Conversation
Onboard the github_actions ecosystem to the per-repo lockfile (`.github/workflows/actions.lock`) authored by the upstream `gh actions-pin` CLI. When a repo has a lockfile that is authoritative for a workflow Dependabot is bumping, regenerate it so the pinned SHAs match the refs Dependabot just wrote. Division of labor: Dependabot keeps ownership of the workflow YAML (the existing regex `uses:` rewrite) and the CLI is the sole writer of the lock. After rewriting the workflow refs, FileUpdater shells out to `gh-actions-pin check --no-onboard --no-narrow` to re-pin the lock to match. `--no-onboard` refuses to onboard brand-new workflows/actions mid-run (surfaced as non-fatal skips); `--no-narrow` preserves the exact ref precision Dependabot chose. Repos without a lock, and workflows the lock does not track, never reach this path, so existing regex-only behavior is unchanged. Key pieces under `lockfile/`: - Reader: read-only parser; per-path onboarding decisions, mandatory hash-algorithm prefixes (sha1-/sha256-) so the eventual SHA-256 transition stays unambiguous, and up-front validation of the keys the engine needs (a malformed entry otherwise makes the engine silently treat the whole lock as empty). - Engine/CliEngine: the injectable seam to the binary. Tri-state exit contract (0 clean, 1 blocking findings with well-formed JSON still on stdout, 2+ tool failure). `findings` is the pre-fix diagnosis, so only the two integrity failures the engine cannot resolve (impostor-commit, lockfile-forgery) block the relock; everything else was already auto-fixed on disk. - Env: builds the subprocess auth/proxy environment for both hosted (tokenless behind a MITM proxy) and proxyless runtimes. - VersionGate: rejects unsupported lockfile schema majors. UpdateChecker preserves divergent per-workflow ref precision instead of collapsing every workflow onto one global target. Hermetic tests stub `Lockfile::Engine.build` at the boundary; the real binary is the only production engine. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pin-contract # Conflicts: # github_actions/lib/dependabot/github_actions/update_checker.rb
Contributor
There was a problem hiding this comment.
Pull request overview
Adds .github/workflows/actions.lock support to the GitHub Actions ecosystem, relocking managed workflows through gh-actions-lock.
Changes:
- Fetches, validates, and version-gates Actions lockfiles.
- Rewrites workflows and regenerates applicable lockfile entries.
- Bundles the native CLI with authentication and error handling.
Show a summary per file
| File | Description |
|---|---|
github_actions/Dockerfile |
Installs verified CLI binaries. |
github_actions/lib/dependabot/github_actions/constants.rb |
Defines lockfile constants. |
github_actions/lib/dependabot/github_actions/file_fetcher.rb |
Fetches the lockfile. |
github_actions/lib/dependabot/github_actions/file_updater.rb |
Coordinates workflow updates and relocking. |
github_actions/lib/dependabot/github_actions/lockfile.rb |
Loads lockfile components. |
github_actions/lib/dependabot/github_actions/lockfile/cli_engine.rb |
Invokes and interprets the CLI. |
github_actions/lib/dependabot/github_actions/lockfile/env.rb |
Builds CLI authentication environment. |
github_actions/lib/dependabot/github_actions/lockfile/errors.rb |
Defines integration errors. |
github_actions/lib/dependabot/github_actions/lockfile/reader.rb |
Parses and validates lockfiles. |
github_actions/lib/dependabot/github_actions/lockfile/version_gate.rb |
Enforces schema compatibility. |
github_actions/lib/dependabot/github_actions/update_checker.rb |
Preserves per-workflow ref precision. |
github_actions/spec/dependabot/github_actions/file_fetcher_spec.rb |
Tests lockfile fetching. |
github_actions/spec/dependabot/github_actions/file_updater_spec.rb |
Tests relock orchestration. |
github_actions/spec/dependabot/github_actions/lockfile/cli_engine_spec.rb |
Tests CLI contracts and findings. |
github_actions/spec/dependabot/github_actions/lockfile/env_spec.rb |
Tests credential environments. |
github_actions/spec/dependabot/github_actions/lockfile/reader_spec.rb |
Tests parsing and validation. |
github_actions/spec/dependabot/github_actions/lockfile/version_gate_spec.rb |
Tests schema gating. |
github_actions/spec/dependabot/github_actions/update_checker_spec.rb |
Tests precision-aware updates. |
github_actions/spec/fixtures/github/contents_githubaction_lockfile.json |
Adds lockfile API fixture. |
github_actions/spec/fixtures/github/contents_githubaction_repo_workflows_with_lock.json |
Adds workflow-listing fixture. |
github_actions/spec/fixtures/lockfiles/actions.lock |
Adds lockfile fixture. |
Review details
- Files reviewed: 20/21 changed files
- Comments generated: 2
- Review effort level: Medium
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
github_actions/lib/dependabot/github_actions/file_fetcher.rb:82
directory != "/"does not mean the job is rooted at.github/workflows; this ecosystem also supports arbitrary directories containing composite actions. In those jobs this fetches<directory>/actions.lock, andReader.from_filesaccepts it by basename, so an unrelated file can influence update selection even though the canonical lock is always.github/workflows/actions.lock. Only use the sibling lookup when the configured directory is the workflows directory; otherwise do not fetch a lock.
path = directory == "/" ? LOCKFILE_PATH : LOCKFILE_NAME
fetch_file_if_present(path)
- Files reviewed: 20/21 changed files
- Comments generated: 1
- Review effort level: Medium
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
github_actions/lib/dependabot/github_actions/package/package_details_fetcher.rb:132
- Returning the matching-precision tag whenever it equals the current version can hide a genuinely newer lower-precision tag.
local_ref_for_latest_version_lower_precisionconsiders every tag with precision less than or equal to the current precision, so with currentv1.1.0and available tagsv1.1.0plusv1.2, this returnsv1.1.0and incorrectly reports the dependency as up to date. Preserve the exact current ref only when the lower-precision candidate is not newer.
lower_precision_ref = git_commit_checker.local_ref_for_latest_version_lower_precision
return ref if ref&.fetch(:version) == current_version
lower_precision_ref
github_actions/Dockerfile:7
- The PR description explicitly says this release-candidate pin is temporary and that the updater image must use stable
v0.1.6and its checksums before merge. The image is still pinned tov0.1.6-rc.2, so the stated merge requirement remains unmet; update this ARG and both architecture checksums to the stable release artifacts.
ARG GH_ACTIONS_LOCK_VERSION=v0.1.6-rc.2
ARG GH_ACTIONS_LOCK_AMD64_CHECKSUM=be371ae7e91b387193a2a6a89cfc2f4c28054fe0fcdfa0b19badc647dae29453
ARG GH_ACTIONS_LOCK_ARM64_CHECKSUM=2a742ccd9430645a6b4834e15867165819583c25cb6d9f6c77c42f9c92b7e135
- Files reviewed: 27/28 changed files
- Comments generated: 0 new
- Review effort level: Medium
AbhishekBhaskar
approved these changes
Jul 28, 2026
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
github_actions/Dockerfile:7
- The PR description explicitly says this release-candidate pin must be replaced before merge, but the updater image still installs
v0.1.6-rc.2. Pin the stablev0.1.6release and update both architecture checksums before approval.
ARG GH_ACTIONS_LOCK_VERSION=v0.1.6-rc.2
ARG GH_ACTIONS_LOCK_AMD64_CHECKSUM=be371ae7e91b387193a2a6a89cfc2f4c28054fe0fcdfa0b19badc647dae29453
ARG GH_ACTIONS_LOCK_ARM64_CHECKSUM=2a742ccd9430645a6b4834e15867165819583c25cb6d9f6c77c42f9c92b7e135
github_actions/lib/dependabot/github_actions/update_checker.rb:118
- An unsupported schema can still affect update selection here because
Readerinterpretsworkflowswithout invokingVersionGate. A v0.0.3/v9 lockfile that names this workflow therefore enables per-source precision inup_to_date?/updated_requirements, even thoughFileUpdaterlater rejects that same file. Gatereader.versiononce this requirement is found onboarded (while preserving the legacy path for untouched workflows), and add corresponding checker coverage.
reader = lockfile_reader
return false unless reader
reader.onboarded?(file.path.delete_prefix("/"))
- Files reviewed: 27/28 changed files
- Comments generated: 0 new
- Review effort level: Medium
AbhishekBhaskar
previously approved these changes
Jul 28, 2026
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
github_actions/spec/fixtures/github/contents_githubaction_lockfile.json:11
- This payload decodes to a
version: v0.0.1lockfile using the oldaction@ref:sha1key format, while this integration accepts only v0.0.2 and the canonical fixture is v0.0.2. As a result, the fetcher test never exercises the supported wire payload and this fixture will fail as soon as it is passed throughVersionGate. Regenerate the encoded content fromspec/fixtures/lockfiles/actions.lock.
"content": "dmVyc2lvbjogdjAuMC4xCndvcmtmbG93czoKICAiLmdpdGh1Yi93b3JrZmxvd3Mvd29ya2Zsb3cueW1sIjoKICAgIC0gImFjdGlvbnMvc2V0dXAtbm9kZUBtYXN0ZXI6c2hhMS01MjczZDBkZjljNjAzZWRjNDI4NGFjODQwMmNmNjUwYjRmMWY2Njg2IgogICIuZ2l0aHViL3dvcmtmbG93cy91bm1hbmFnZWQueW1sIjoKICAgIC0gImFjdGlvbnMvY2hlY2tvdXRAdjQ6c2hhMS0zNGUxYzBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwIgpkZXBlbmRlbmNpZXM6CiAgImFjdGlvbnMvc2V0dXAtbm9kZUBtYXN0ZXI6c2hhMS01MjczZDBkZjljNjAzZWRjNDI4NGFjODQwMmNmNjUwYjRmMWY2Njg2IjoKICAgIGJyYW5jaDogbWFzdGVyCiAgICBjb21taXQ6IDUyNzNkMGRmOWM2MDNlZGM0Mjg0YWM4NDAyY2Y2NTBiNGYxZjY2ODYKICAgIG93bmVyX2lkOiA0NDAzNjU2MgogICAgcmVwb19pZDogMTY3Mjc0NDgxCiAgICB0YWc6IG1hc3RlcgogICJhY3Rpb25zL2NoZWNrb3V0QHY0OnNoYTEtMzRlMWMwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMCI6CiAgICBicmFuY2g6IG1haW4KICAgIGNvbW1pdDogMzRlMWMwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMGUwZTBlMAogICAgb3duZXJfaWQ6IDQ0MDM2NTYyCiAgICByZXBvX2lkOiAxOTc4MTQyODAKICAgIHRhZzogdjQK\n",
- Files reviewed: 27/28 changed files
- Comments generated: 0 new
- Review effort level: Medium
AbhishekBhaskar
approved these changes
Jul 29, 2026
This was referenced Aug 9, 2026
Closed
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.
What
Add Dependabot support for
.github/workflows/actions.lock.Scope
GitHub.com only. Existing lockfiles only; no automatic onboarding.
Testing
Focused specs and staging dry-runs.