GitHub Actions workflow lockfiles are generally available #194494
Replies: 12 comments 10 replies
|
Thank you for opening this discussion. I think this proposal is important because it addresses a concrete GitHub Actions instance of a broader architectural condition I previously isolated as architectural non-determinism: the reviewed object and the executable object can diverge unless the effective execution context is fixed before execution. Reference: Identical Inputs, Divergent Outcomes: Architectural Non Determinism as a Governance and Liability Risk. So my question is: could GitHub expose the resolved dependencies: graph as an input to policy/security tooling before run admission, so that automation-created or AI-assisted workflow changes can fail closed before any job executes? That would make dependency locking not only a reproducibility mechanism, but a pre-execution admission surface. |
|
First thoughts:
|
|
One major difference between the sha based locking and traditional lockfiles is that the latter often include a hash of the contents of the dependency. While the SHA itself might not be mutated, an action can easily include things that can change, e.g. because they're pulling in external things. So it kinds sounds like the SHA based approach is just kicking the can down the road? For example, Python's |
|
I don't really see how any of this will work for me. I'd love for a human to spend some time talking to me, but I also want to talk about other things, so it's a tradeoff. My stack has (some optional, some not) dependencies from:
Many of these dependencies are optional (hunspell is only needed if a workflow asks to use hunspell dictionaries; tesseract is only needed if a workflow asks to check images, ...) or can be provided by the caller (if a dependency is already available and has a satisfactory version, it'll be used as is, e.g. Classically, build systems aiming for reproducible builds tended to fail miserably because they neglected to record information about what the OS provided, or about transient dependencies that were satisfiable by some In theory, GitHub's runner images themselves are fully pinned, but almost nothing in the apt world is truly fully pinned, and most apt packages (especially those that use -devel/-dev headers) don't fully pin, which means that the binaries they provided themselves aren't truly reproducible -- but if you rely on a specific signed binary package, you could at least go for "traceable". (I worked on a Debian based linux distribution for 5 years, and quickly learned that the version definitions people imagined did not apply to rebuildable binaries.) -- And I should note that GitHub's runners turned out to be considerably more nondeterministic than people expected (the GitHub Runner itself can significantly influence how a runner image behaves -- ask me how I know). Would people be interested in providing a way for actions to provide a SBOM/BOM reporting which things they retrieved so that someone who is curious could review that and try to reproduce a build by satisfying the SBOM/BOM contents before running steps? I'm not strictly opposed to providing an SBOM-like thing if someone provided an easy way to do so. (Requiring users to pay for GitHub Advanced Security or requiring Which CPAN package manager would people actually expect developers to use to satisfy the goals presented here? https://github.com/tokuhirom/anton (died 12 years ago) A number of my GitHub action dependencies are runtime selected. e.g., actions/upload-artifact is only used in some cases, and when it isn't used, my action does not download it. A pinning file that forced all possible dependencies to be downloaded even in cases where they weren't used would waste immense amounts of time. -- I work very hard to make my action start quickly -- I took the effort to replace github/codeql-action because it had a really horrible packaging story (they've since fixed it, but I have no intention of adding it as a dependency going forward). Note that Debian/Ubuntu images themselves do not pin the world, and even GitHub kicks packages out to make space (GitHub's setup-java action broke scala at some point and didn't care to fix it when GitHub dropped sbt or something), they just provide the ability to dynamically add packages based on requests (apt-get install). Also fun, Similarly, my action can use any number of external dictionaries (configured by the workflow caller). It does not make sense for me to bundle an infinite number of potential dictionaries into my action or into a dependency lock file (beyond the fact that it's obviously impossible), as the specific dictionaries that a consumer will use will vary based on the consumer. I'm more than happy to provide URLs and SHAs for such files (again, see SBOM), but I can't reasonably inline such content into my action. @samus-aran I'm open to a call (or a recurring call, I collect these). But, I'd also encourage you to take a look at my action first. |
|
Personally, i'd prefer to see the hashes in a separate single lockfile (for the whole repo, and/or per workflow) - for CODEOWNERS control, diff churn, etc. In other words, like in almost every ecosystem, the dependency manifest should be separate from the lockfile. |
|
This sounds like a great endeavor! I'm excited for it :D I will echo the preference for the I'd also prefer to avoid using comments to indicate transitive dependencies. My motivation comes from two directions:
Maybe a lockfile format like this? .github/workflows/dependencies.lock # Automatically generated and managed by gh-actions-pin
<workflow-1.yml>:
- name: github.com/actions/checkout@v4.3.1:sha1-34e114876b0b11c390a56381ad16ebd13914f8d5
- name: github.com/nodeselector/actions-test-fixtures/nested-composite@updated:sha1-ea53476fdc172d8552df5af9658a45a367e4f41d
dependencies:
- name: github.com/nodeselector/actions-test-fixtures/simple-composite@main:sha1-d010fee89969c44873ca2c1b501905190eb7410d
dependencies:
- github.com/nodeselector/actions-test-fixtures-b/simple-echo@main:sha1-92b7b0058bc223c6e9dd4e19ef9247c934ba7637
- github.com/nodeselector/actions-test-fixtures/simple-node@main:sha1-d010fee89969c44873ca2c1b501905190eb7410d
<workflow-2.yml>:
- name: ...I don't have meaningful experience building package management ecosystems, so I'm happy to be corrected on the feasibility of this proposed lockfile format. I recognize that a flat list is easier to load than a recursive walk, but a richer structure akin to the one I've sketched here would be helpful. |
|
Speaking as zizmor's maintainer, I think my primary concerns are:
Like others, I think I would strongly prefer it if GitHub were to pursue a detached lockfile approach here. Going even further, I think it would be really great if the ultimate lockfile was global across all workflows, and not just per-workflow. In other words, I think it would be really great if there was a single Finally, I think it would be great for GitHub to ideate (if not necessarily share) long-term plans for making locked resolutions of actions mandatory, rather than opt-in. Users would ideally not have to opt into locking, because the median user won't. Edit: I'll also echo the sentiment that, whatever GitHub does here, it should not continue the unfortunate trend of communicating important semantic information (like transitive relationships) via non-semantic state (YAML comments). Ideally a lockfile/lock representation here would be an actual machine-readable graph representation like |
|
We're pinning all of our actions in |
|
Do you still plan to keep the current behavior of using git as binary repository? If not, and if you plan to finally support an OCI images registry or another file registry, the lock file should also include the origin. |
|
It would be nice to be able to pin permissions (OCAP-style) separately from SHAs - i'd love to avoid the problems caused by pinning SHAs, allowing free-flowing updates - but lock down the permissions a workflow has, ensuring that if they widen, the update is blocked. |
|
If I have already enabled steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 |
🆕 Community Manager Update: October 28, 2026Hi everyone! Thank you so much for leaving feedback. We're happy to announce: GitHub Actions workflow lockfiles are generally available. Please read the updated the discussion above and continue to leave comments if you have additional thoughts. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
You can now use GitHub Actions workflow dependency lockfiles in general availability on GitHub Enterprise Cloud, GitHub Enterprise Cloud with data residency, Team, and Free plans. Lockfiles let you keep readable tag and branch references in your workflows while running the exact commits you locked, even if those references move.
This release brings the capabilities introduced in the public preview to general availability:
gh actions-lockextension for the GitHub CLI to generate.github/workflows/actions.lockfor actions, their transitive dependencies, and reusable workflow references.Lockfiles help protect against unexpected dependency changes, but they don't determine whether a dependency is safe. Review dependencies before locking them.
Get started
Install the extension from the gh-actions-lock repository, then review and commit the generated lockfile and workflow changes. See workflow dependency lockfiles in GitHub Docs for details and setup instructions.
🌟 Leave a comment!
Share feedback in the comments below or report an issue with the extension.
Tune in for Day 2 of GitHub Universe & check out our round-up post of releases in the Community that need your input ⏭️
All reactions