Warning
Public preview. gh-actions-lock is pre-1.0. The lockfile format, flags, and behavior may change between releases.
A GitHub CLI extension that pins every direct and transitive action your workflows use to a verified commit, recorded in .github/workflows/actions.lock.
Requires an authenticated gh. github.com and GitHub Enterprise Cloud with data residency (*.ghe.com) are supported; GitHub Enterprise Server is not.
gh extension install github/gh-actions-lockTo teach your AI coding agent the CLI:
gh skill install github/gh-actions-lockFrom the repository checkout:
gh actions-lock # onboard or fix: pin every resolvable action and write actions.lock
git add .github/workflows/ # check into sourceRerun gh actions-lock after adding a workflow or changing any uses:.
Make sure you don't check in a corrupt lockfile. Copy .github/workflows/verify-lockfile.yml into your repository, modify it for your needs, then run gh actions-lock once so that workflow is locked too.
Run gh auth login --hostname TENANT.ghe.com, then run gh actions-lock from the tenant repository checkout. The host comes from the repository remote; you don't need --hostname or an exported token.
Actions that aren't on the tenant, such as actions/checkout, are read from public github.com repositories. Those lookups never use the tenant token, GH_TOKEN or GITHUB_TOKEN. They use, in order:
GH_ACTIONS_LOCK_GITHUB_COM_TOKEN, a github.com token used only for these lookups.- Your
gh auth login --hostname github.comlogin. - Otherwise they're anonymous and share GitHub's limit of 60 requests an hour per IP address, which a shared proxy or runner pool can exhaust quickly.
In GitHub Actions on GHE.com, the job's GITHUB_TOKEN is issued by your tenant, so github.com doesn't accept it. Create a fine-grained personal access token on github.com with public repository access only and no permissions, save it as a secret on the tenant, and pass it in:
- run: gh actions-lock --verify
env:
GH_TOKEN: ${{ github.token }}
GH_ACTIONS_LOCK_GITHUB_COM_TOKEN: ${{ secrets.ACTIONS_LOCK_GITHUB_COM_TOKEN }}| Command | Writes | Network | Use for |
|---|---|---|---|
gh actions-lock |
yes | yes | Onboarding and fixing the lockfile |
gh actions-lock --relock |
yes | yes | Advancing moved refs (main, v4) to current upstream commits |
gh actions-lock --verify |
no | yes | CI: the same checks as a fix run |
gh actions-lock --verify-local |
no | no | Pre-commit: every uses: has a lockfile entry (coverage only, not provenance) |
gh actions-lock --no-fix |
no | yes | Read-only report |
Other flags:
<workflow-path>...scopes a run to specific workflows. Only a full-directory run prunes entries for deleted workflows.--json [fields]prints machine-readable output to stdout.--accept-movedaccepts pins whose locked commit is no longer upstream. Check why it moved first; never use it in automation.--no-narrowkeeps partial versions (v4) as written instead of narrowing to a full tag.
gh actions-lock --help is authoritative.
- Reusable workflows called at
jobs.<id>.usesfrom another repository are not locked (#179). - Local
./…actions are never followed or locked, so one that uses remote actions is a blocking error until you pass--migrate-local-actions(rewrites same-repo./…to$/…) or--ignore-local-actions. - Container images are not locked, and any image without an
@sha256:digest, including one chosen by a${{ }}expression, is a warning (#236). --verify-localis an offline coverage check that doesn't verify provenance;--verifychecks provenance before merge, and the runner checks it again at job start.- A lockfile change that moves a floating ref (
v4,main) back to an older commit in its history isn't detected, so review lockfile diffs or pin exact tags.
See CONTRIBUTING.md
See SUPPORT.md.
Licensed under MIT.