You know that recipe card your grandmother kept? "Add a pinch of salt." Great, until the pinch turns out to be different every time. Now imagine your deployment pipeline works the same way: uses: some-action@v3 means "run whatever v3 points to today."
That's the quiet risk in most CI/CD pipelines. A tag or branch can move after you reviewed the workflow, so a later run can execute different code, with no change in your repository to warn you. If an action gets compromised, a moved tag does the damage while your pull request history sits there looking innocent.
GitHub's answer arrived on October 14: workflow dependency lockfiles, now in public preview. And in the same month, another change quietly landed that can break pipelines on its own: Node 20 is gone from Actions runners.
Two changes, one afternoon of work. Let's do this properly.
What We Are Cooking Today
- Understand what a workflow lockfile pins, and what it doesn't
- Audit which actions your workflows depend on
- Adopt locking gradually, one workflow at a time
- Fix the Node 20 to Node 24 change before it breaks a pipeline
What's New
Workflow dependency lockfiles (public preview, October 14)
According to GitHub's changelog, lockfiles let you keep readable references like tags in your workflow while running the exact commits you locked. Highlights:
- It pins transitive dependencies too. The generated
.github/workflows/actions.lockcontains reviewable commits for actions, their transitive dependencies, and reusable workflow dependencies. - Gradual adoption. You onboard workflows individually. Once onboarded, a workflow must have lockfile entries for its dependencies, and Actions runs the recorded commits even if a tag or branch moves.
- Stale-lockfile checks. You can verify the lockfile is current without modifying files, including inside a CI check.
- A "Require lockfile" policy. Enterprise, organization, and repository admins can require workflows to use lockfiles. It's also in public preview.
- Dependabot integration. When Dependabot bumps an action in an onboarded workflow, it regenerates the matching lockfile entry in the same pull request.
- Availability. Public preview on GitHub Enterprise Cloud (including data residency), Team, and Free plans.
An important caveat, straight from GitHub: locking doesn't tell you whether a dependency is safe. It only freezes what you reviewed. Review first, then lock.
Node 20 is no longer available (September 23)
GitHub called this the final notification: Actions runners now use Node 24 for JavaScript actions, and the temporary ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION opt-out is gone. If you maintain a JavaScript action, set runs.using to node24 and publish a new release. If you only use actions, update to versions that support Node 24. GitHub says the newest versions of all first-party actions already do. Node 24 isn't compatible with macOS 13.4 and earlier and doesn't officially support ARM32, so self-hosted runners on those platforms are no longer supported.
Lockfile vs. SHA Pinning
If you followed our recent patch-week checklist and started pinning actions to full commit SHAs, good. Lockfiles are the next step up, not a replacement for your judgment:
| Manual SHA pinning | Workflow lockfile | |
|---|---|---|
| Readability | Opaque hashes, tag in a comment | Tags stay in the workflow |
| Transitive dependencies | You pin only what you wrote | Recorded in the lockfile |
| Enforcement | Convention and code review | Runtime requirement for onboarded workflows, plus an optional org policy |
| Updates | Dependabot or Renovate PRs | Dependabot regenerates entries in the same PR |
| Maturity | Works everywhere today | Public preview, so details may change |
Ingredients
- A repository on a plan that has the preview (Enterprise Cloud, Team, or Free)
- The GitHub CLI (
gh), authenticated - A low-risk workflow to practice on first
- Dependabot enabled for GitHub Actions updates
- About an hour
Kitchen Prep
Before locking anything, know what you depend on. Locking an unreviewed dependency just freezes the risk in place.
# Every action your workflows use, most-used first
grep -rhoE "uses: *[^ ]+" .github/workflows/ | sort | uniq -c | sort -rn
For each third-party action, ask three questions: Who maintains it? When was it last updated? Do I actually need it, or is it a three-line shell step in disguise? Deleting a dependency is the best lockfile entry of all.
Recipe Steps
Step 1: Fix the Node 24 issue first
It's the one that can fail your build tomorrow. Find JavaScript actions that still declare an old runtime. In any action repositories you maintain:
grep -rn "using:" action.yml action.yaml 2>/dev/null
Change using: node20 to using: node24, test, and cut a release. For third-party actions you consume, bump to the latest version and read its release notes. Check your self-hosted runners too: macOS 13.4 or earlier, or ARM32, are no longer supported.
Step 2: Install the lockfile tooling
gh extension install github/gh-actions-lock
gh actions-lock --help
GitHub's announcement names the extension but not every subcommand, and this is a preview, so I'm not going to guess at flags. Run --help and follow the setup instructions in the GitHub Docs page on workflow dependency lockfiles.
Step 3: Generate the lockfile for one workflow
Pick a low-risk workflow (a linter or docs build, not your production deploy). Use the extension to onboard it. This should produce .github/workflows/actions.lock plus any workflow changes. Then read the diff. Open the recorded commits for the actions that matter. This is the review step GitHub says locking doesn't replace.
Step 4: Commit and watch a run
Open a pull request with the lockfile and workflow changes. Once the workflow is onboarded, Actions requires each of its dependencies to appear in the lockfile and runs the recorded commits. A missing entry is the failure you want to discover on a practice workflow, not on your release pipeline.
Step 5: Add a stale-lockfile check to CI
The extension can verify the lockfile is up to date without modifying files, so it fits naturally in a CI job. Add it as a required check on pull requests that touch .github/workflows/. Check gh actions-lock --help for the exact verify command in your version.
Step 6: Let Dependabot do the boring part
Make sure your Dependabot config updates the github-actions ecosystem:
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
For onboarded workflows, GitHub says Dependabot regenerates the matching lockfile entry in the same pull request, with no extra configuration.
Step 7: Consider the org-level "Require lockfile" policy
Once a few workflows are happily locked, admins can require lockfiles across a repository, organization, or enterprise. Roll this out gradually. A blanket requirement on day one means everyone's pipelines fail on day one, and then the policy gets disabled on day two.
Chef Tips
- Onboard deploy workflows last, but onboard them. They have the most to lose, and the most secrets to protect.
- Treat lockfile diffs like code. A reviewer should look at what changed, not rubber-stamp a generated file.
- Combine it with the execution protections GitHub released in September. One controls who and what can start a workflow. The other controls which code it runs. They solve different halves of the problem.
- Delete unused actions. Every dependency is a trust decision you'll keep paying for.
Kitchen Disasters
| Symptom | Likely cause | Fix |
|---|---|---|
| Onboarded workflow fails: dependency not in lockfile | Workflow changed without regenerating the lockfile | Regenerate with the extension and commit both files |
| JavaScript action errors after the runner update | Action still targets a removed Node runtime | Update to a version using node24, or publish one if it's yours |
| Self-hosted runner stops working | Unsupported OS or architecture for Node 24 (macOS 13.4 and earlier, ARM32) | Move the runner to a supported platform |
| Dependabot bumps the workflow but the build fails on the lockfile | Workflow isn't onboarded or the entry wasn't regenerated | Check the PR for the regenerated lockfile entry; onboard the workflow if needed |
| Teammates revolt after "Require lockfile" is enabled | Policy applied before workflows were onboarded | Roll out by repository, with a migration window |
Serving Suggestions
- Add a quarterly "CI dependency review" to your calendar. Check who maintains each action and whether you still need it.
- Track GitHub's Actions changelog. This month alone included the lockfile preview, Node 20 removal, Ubuntu 26 and
ubuntu-latestmigration notes, and retention changes. Read the notes for any runner image your workflows depend on. - Write down which workflows are onboarded, so "are we protected?" has a real answer.
Cleanup
If you tried locking on a practice workflow and decided to pause, remove that workflow's entries and the lockfile changes in a pull request, so nothing is half-onboarded. Half-locked pipelines are the confusing kind.
Frequently Asked Questions
Does a lockfile make my pipeline safe?
No. GitHub says so explicitly: locking doesn't determine whether a dependency is safe. It stops silent changes after you've reviewed it.
Do I have to lock every workflow at once?
No. You can onboard workflows individually. Once onboarded, a workflow must have lockfile entries for its dependencies.
Is this ready for production?
It's a public preview, so expect changes. It's a good time to try it on low-risk workflows and give feedback, and a sensible time to wait on your most critical pipelines.
Does the Node 24 change affect me if I only use other people's actions?
Possibly. If an action you use still targets an old runtime, it can fail. Updating to the latest version of each action is the fix, and GitHub says its first-party actions are already updated.
Final Thoughts
Most CI/CD incidents aren't clever. They're ordinary pipelines running slightly different code than anyone reviewed. Lockfiles close that gap, and the Node 24 change is a reminder that the platform under your pipeline moves too. Fix the runtime issue first, onboard one workflow, read the diff, and build from there. Your pipeline should run the recipe you tasted, not whatever the pinch turned into.
No comments:
Post a Comment