
GitHub Actions workflow lockfiles are now GA: Trying out how to prevent missed updates and forgotten onboarding with CI, Dependabot, and policies
This page has been translated by machine translation. View original
Hello! I'm Yuji Nishimura from the Operations Department!
GitHub Actions workflow lockfile became generally available on October 28, 2026. It records the commits of the actions a workflow references, and of the actions called within them, in .github/workflows/actions.lock, and fetches those commits at run time. Besides generating the lockfile, the GA announcement introduces three more things: detecting a stale lockfile in CI, updates via Dependabot, and the Require lockfile policy that makes a lockfile mandatory.
If you only want to create a lockfile, running gh actions-lock once is enough. The documentation calls registering a workflow in the lockfile “onboarding”. To run it in practice, though, you need to decide where to catch a missed lockfile update and how to stop workflows that were never onboarded. On top of that, Require lockfile is not enforced depending on your plan and the repository's visibility. This article combines CI, Dependabot, and Require lockfile, and also sorts out how to use them alongside SHA pinning enforcement in environments where Require lockfile is not enforced.
I checked this on November 2, 2026. The environment was as follows.
- A repository created under a Free plan account (created as private, then changed to public to try Require lockfile)
- GitHub-hosted
ubuntu-latestrunner - gh 2.103.2 and gh actions-lock v0.4.0 locally (installed with
gh extension install github/gh-actions-lock)
I did not try the following.
- Policy settings in an Organization, and enforcement in private repositories. The scope of enforcement is a judgment based on the on-screen notice and the documentation
- Restricting the Require lockfile target to some workflows, and the Evaluate mode that only records violations. This article does not tell you the steps for a gradual rollout
- Reusable workflows located in another repository
- How merges get blocked when the verify check is made required with branch protection or a ruleset
- Dependabot security updates and grouping
I covered how the lockfile itself works in an earlier article during the public preview.
Conclusion first: the recommended setup
From these results, the following combination looks good.
| Mechanism | Role | Settings and notes |
|---|---|---|
| lockfile (gh actions-lock) | Pins actions and their inner dependencies by commit | Onboard with the latest gh actions-lock. Onboard new workflows yourself |
--verify in CI |
Shows mismatches between the lockfile and workflows, and missed onboarding, as a PR check | Raise the official sample's --pin v0.2.0 to --pin v0.4.0, the latest at the time of checking |
| Dependabot | Updates the lockfile together in version update PRs | Just configure github-actions |
| Require lockfile policy | Stops every workflow that has not been onboarded before it starts | With “All workflows”, even workflows that use no actions must be onboarded |
| SHA pinning enforcement | Stops references that are not full SHAs (tags or branches) in workflows that have not been onboarded | Onboarded workflows pass even with tag references |
Require lockfile is enforced in public repositories and in private repositories on GitHub Team or GitHub Enterprise (based on the documentation and the on-screen notice). How you stop missed onboarding depends on whether it is enforced.
- Public repositories, and private repositories on Team or higher: combine Require lockfile with the lockfile,
--verifyin CI, and Dependabot - Free private repositories: enable SHA pinning enforcement instead of Require lockfile. Workflows written with full SHAs run even if not onboarded, so catch them with
--verifyin CI
There were two pitfalls. One is that when a PR forgets to update the lockfile and an onboarded workflow fails to start, that failure does not appear in the PR's check list. The other is that the official sample CI is pinned to gh actions-lock v0.2.0, and the --verify of v0.2.0 can let through a lockfile that will fail at run time. Both were caught by running --verify in CI with the latest gh actions-lock.
The following diagram is a conceptual diagram I made myself, not an official architecture diagram. The left is the entry points of changes, the center is PR checks, and the right is the results at run time.

Setting up CI, verify, and Dependabot in the test repository
I placed three things in the test repository: ci.yml for CI, verify-lockfile.yml from the gh actions-lock official sample, and the Dependabot configuration.
name: ci
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: echo "build"
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
I used the official sample from the v0.4.0 tag as is.
# Fails when .github/workflows/actions.lock is out of sync with the
# workflows or a locked pin no longer verifies upstream.
name: verify-lockfile
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- run: gh extension install github/gh-actions-lock --pin v0.2.0
- run: gh actions-lock --verify
When I ran gh actions-lock locally without arguments, both workflows were onboarded. This time, @v6 in ci.yml was rewritten to the full version tag @v6.1.0.
gh actions-lock
Scanning 2 workflows
Planning pins
Pinned 2 actions across 2 workflows
actions/checkout@v6.1.0 (d23441a)
└─ .github/workflows/ci.yml
actions/checkout@v7.0.1 (3d3c42e)
└─ .github/workflows/verify-lockfile.yml
After pushing the workflows and the lockfile, both ci and verify-lockfile succeeded.
In a PR with a stale lockfile, only the verify failure shows up in the checks
I added an actions/cache@v4 step to ci.yml and opened a PR without updating the lockfile. At this point, I had already changed the repository to public, but neither Require lockfile nor SHA pinning enforcement was enabled yet.
Looking with gh pr checks, the only thing that appeared in the PR's checks was the verify-lockfile failure. gh pr view --json statusCheckRollup also shows just the one verify entry. I did not check the PR screen.
gh pr checks 2
verify fail 6s https://github.com/ynishimura/blog-verify-lockfile-ops/actions/runs/41453374622/job/125303855861
The verify-lockfile log points out the action that is not recorded in the lockfile.
1 of 2 workflows failed
✗ Not pinned actions/cache@v4
used in workflow but not pinned in lockfile (actions/cache@v4)
On the other hand, the run of the modified ci.yml itself was startup_failure. No jobs were created, and it did not appear in the PR's checks either. It does remain in the Actions run list, though.
gh run list --branch add-cache-without-lock --json workflowName,event,conclusion --jq '.[]|[.workflowName,.event,.conclusion]|@tsv'
ci pull_request startup_failure
verify-lockfile pull_request failure
In the earlier article too, a run pushed without updating the lockfile in a private repository became startup_failure. A startup failure caused by a stale lockfile happens regardless of policies or visibility. This time, verify-lockfile was the only thing that surfaced a missed lockfile update as a PR check. To block the merge, it seems you need to make the verify check required with branch protection or a ruleset, but I did not try that this time.
Raise --pin when using the official sample CI
The official sample pins the gh actions-lock version with --pin v0.2.0. The latest as of November 2, 2026 is v0.4.0. The --verify judgment changed in v0.3.0, and the release notes say “Some lockfiles that passed --verify on v0.2.0 now fail it”.
When I tried SHA pinning enforcement, a workflow using a lockfile made with v0.2.0 failed at run time with the error lockfile missing pin for actions/checkout@v7. That workflow referenced a composite action that uses actions/checkout@v7 internally. v0.2.0 recorded the actions/checkout@v7 inside the composite action as actions/checkout@v7.0.1, so it reads as though the @v7 entry could not be found at run time.
I compared --verify of v0.2.0 and v0.4.0 against this lockfile. I installed v0.2.0 by pointing the gh extension storage location (XDG_DATA_HOME) to a temporary directory, keeping it separate from the local v0.4.0.
gh actions-lock --verify .github/workflows/t13-locked.yml
v0.2.0 judged it as having no problems.
Scanning 1 workflow
All 1 workflow valid
v0.4.0 detected that the reference inside the composite action is not recorded in the lockfile (excerpt of the output).
Scanning 1 workflow
1 of 1 workflow failed
✗ Lockfile doesn't match locked manifest actions/checkout@v7
ynishimura/blog-verify-sha-pinning/.github/actions/composite-tag@v1 at locked commit b49117c7d739 uses actions/checkout@v7, but its lockfile entry ynishimura/blog-verify-sha-pinning@v1 does not record it
! restore the edge from version control, or run `gh actions-lock --relock`
see: https://github.com/github/gh-actions-lock/blob/main/docs/troubleshooting.md#incomplete-lockfile
If you keep using the sample with --pin v0.2.0, CI can let through a lockfile that is missing references inside a composite action. This time I changed it to --pin v0.4.0 and confirmed that verify-lockfile succeeds even with both Require lockfile and SHA pinning enforcement turned on, which I enable later.
- run: gh extension install github/gh-actions-lock --pin v0.4.0
A lockfile created back in the v0.2.0 days can end up with incomplete-lockfile in --verify once you raise --pin. In that case, recreate it with gh actions-lock --relock (confirmed in the article where I tried SHA pinning enforcement). If you pin the version, the judgment won't suddenly change because of a gh actions-lock update. In exchange, you will need to raise the --pin value in step with gh actions-lock releases.
Dependabot updates the lockfile in the same PR
When I placed dependabot.yml and pushed, Dependabot immediately opened a PR (#1) raising actions/checkout from 6.1.0 to 7.0.1. Two files changed: ci.yml and actions.lock. In the lockfile, the ci.yml entry changed to actions/checkout@v7.0.1, and the no-longer-used actions/checkout@v6.1.0 entry was removed. The v7.0.1 entry already existed for verify-lockfile.yml.
workflows:
'.github/workflows/ci.yml':
- - 'actions/checkout@v6.1.0'
+ - 'actions/checkout@v7.0.1'
'.github/workflows/verify-lockfile.yml':
- 'actions/checkout@v7.0.1'
dependencies:
- 'actions/checkout@v6.1.0':
- ref: 'v6.1.0'
- commit: 'sha1-d23441a48e516b6c34aea4fa41551a30e30af803'
- owner_id: 44036562
- repo_id: 197814629
build and verify on the PR succeeded. I describe the results with the policies enabled in a later section.
However, Locking action dependencies in a repository's workflows says “Dependabot only updates lockfile entries for workflows that are already onboarded.” Dependabot does not go as far as onboarding new workflows.
What Require lockfile stops
It is not enforced in Free private repositories
Require lockfile is a policy you create under “Settings” → “Actions” → “Policies”. When I opened this screen with the repository still private, the following notice appeared. The red frame was added by me.

The “Who can use this feature?” section of Governing execution of GitHub Actions workflows also says “All public repositories, and private repositories on GitHub Team or GitHub Enterprise.” I did not try creating and running the policy while the repository was private. This time I changed the test repository to public and went on from there. Once it was public, this notice disappeared.
Creating the policy
From “New policy”, I gave it a name, checked “Require lockfile”, and set Enforcement status to “Active”. Target workflows was left at “All workflows”. The red frame was added by me.

The options for Enforcement status were just Active and Disabled. According to the documentation, Evaluate is available only on GitHub Enterprise Cloud. Also, on the November 2, 2026 screen, Require lockfile still carried a “Preview” label even after the GA announcement.
Workflows that are not onboarded are stopped regardless of whether they use actions or are SHA-pinned
With the policy enabled, I added two workflows that were not onboarded. One uses actions/checkout@v7.0.1, and the other uses no actions and has only a run step. Both became startup_failure. The onboarded ci.yml succeeded. The red frame was added by me.

The full text of the annotation is as follows.
Workflow is not in the repository's lockfile. Run `gh actions-lock` in the repository and commit the result. If this is a reusable workflow, the maintainer of the reusable workflow needs to run `gh actions-lock` in its repository and commit the result. Workflow file: '.github/workflows/new-run-only.yml'.
The documentation also says Require lockfile stops workflows that use no actions, “including workflows with no uses: dependencies”. The verify-lockfile that ran on the same push also pointed out the missed onboarding with ✗ Not pinned .github/workflows/new-run-only.yml / workflow has no lockfile entry.
Next, I also enabled SHA pinning enforcement (“Settings” → “Actions” → “General”, “Require actions to be pinned to a full-length commit SHA”). In this state, I added a release.yml that pins actions/checkout with a full SHA, without onboarding it. This was also startup_failure. Even if pinned with a full SHA, Require lockfile stops it unless it is onboarded.
If you target “All workflows”, you need to onboard every workflow in the repository.
Onboard new workflows yourself
To get the stopped release.yml through, I onboarded only this workflow.
gh actions-lock .github/workflows/release.yml
At this point, the full SHA reference that had the tag attached as a comment was rewritten to that tag notation.
- - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: actions/checkout@v7.0.1
When I pushed the workflow and the lockfile in the same commit, release.yml also succeeded. When adding a workflow, the flow is to run gh actions-lock <workflow> and put the workflow and the lockfile in the same commit. References that were pinned with a full SHA become tag notation, so if you have anything that assumes SHAs are used (for example, a CI check that tests whether a reference is a SHA), you need to review it.
How to combine it with SHA pinning enforcement
According to the documentation, Require lockfile is a separate policy from SHA pinning enforcement, and it is fine to enable both during a migration. This time too, with both enabled, the following three succeeded.
ci.ymlandverify-lockfile.yml, which are onboarded and use tag references- The Dependabot update job (
Dependabot Updates) - After adding
actions/setup-node@v4toci.ymland onboarding it, the PR (including the lockfile) that Dependabot opened to raiseactions/setup-nodefrom 4.4.0 to 7.1.0, and the checks on that PR
The policy creation screen also said that features such as Dependabot are outside the scope of this protection.
The two policies stop different things.
| Policy | What it stops | Free private repositories |
|---|---|---|
| Require lockfile | Workflows that are not onboarded (regardless of whether they use actions or are SHA-pinned) | Not enforced |
| SHA pinning enforcement | References that are not full SHAs in workflows that are not onboarded (fails at Set up job) | Enforced (confirmed in the article where I tried SHA pinning enforcement) |
In an environment where Require lockfile is enforced, it has the wider scope and can stop all workflows that were not onboarded in one go. In Free private repositories, use SHA pinning enforcement to stop tag references in workflows that were not onboarded. Workflows written with full SHAs and workflows that use no actions will run, so catch them with --verify in CI.
Summary
With the now-GA workflow lockfile, onboarding with gh actions-lock and combining it with --verify in CI and Dependabot let me manage it in the same PR as the workflow. In a PR that forgets to update the lockfile, an onboarded workflow just becomes startup_failure and does not show up in the PR's checks. Without --verify, the PR checks alone won't let you notice a missed update, so if you use the official sample, you'll want to raise --pin to the latest. Dependabot does not onboard new workflows, so run gh actions-lock <workflow> yourself.
How to stop missed onboarding depends on your plan and the repository's visibility. I plan to use Require lockfile for public repositories and private repositories on the Team plan or higher, and SHA pinning enforcement instead for Free private repositories.
I hope this helps someone.
Reference links:
- GitHub Actions workflow lockfiles are generally available
- Workflow dependency lockfiles
- Locking action dependencies in a repository's workflows
- Enforce workflow lockfiles
- Governing execution of GitHub Actions workflows
- github/gh-actions-lock
- verify-lockfile.yml (official sample for gh-actions-lock v0.4.0)
- gh-actions-lock v0.3.0 release notes
- Enforcing SHA pinning for GitHub Actions through settings. Trying out what gets stopped, and whether a lockfile lets tags through
- Trying out GitHub Actions workflow lockfiles. Pinning dependencies to commits with actions.lock, and stopping before execution when they drift