@andrewnez sometime I feel all these github action should have been just a python/bash script...
especially when you need 100 commits to get it right and had to trust the code of 2-4 contributors/organisations to do so.
this would make more sense to me : https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies
with https://github.com/astral-sh/uv/issues/6318
@mestachs @andrewnez Nothing prevents you from making a very simple workflow that checks out your repo and then calls a script you have full control over.
All actions are mostly just convenience.
Scripts shared by strangers you can run and don't have to copy/paste from gists or stackoverflow.
@andrewnez Yikes, it's worse than I thought. Thanks for the writeup.
Maybe they'll get around to fixing things after the AI bubble bursts... ?
@andrewnez i think there's a slippage of terminology here too:
The core problem is the lack of a lockfile. Every other package manager figured this out decades ago: you declare loose constraints in a manifest, the resolver picks specific versions, and the lockfile records exactly what was chosen.
for one, the resolver is only as powerful as the constraints. if your constraints are limited to name and simple version matching, then a lockfile is indistinguishable from a manifest—we see this from pip freeze, which is actually quite notable for not being a lockfile.
@andrewnez python has per-platform and per-python-version constraints, for which you'll need something like pip install --report to get a "locked" experience. that feature was a generalization of my work here https://github.com/pantsbuild/pants/pull/8793 which was able to lazy-load python requirements upon execution.
the poetry package manager has a truly fascinating system where it resolves a dependency tree across several target platforms at once. it's able to do this though because python packaging protocols have had a lot of people caring about them for many years.

Problem See pex-tool/pex#789 for a description of the issue, and https://docs.google.com/document/d/1B_g0Ofs8aQsJtrePPR1PCtSAKgBG1o59AhS_NwfFnbI/edit for a google doc with pros and cons of differen...
Content warning: ngi app on capillary the rust build tool
@andrewnez Just read through your post on Actions and it has a lot of valid criticism.
It's also still missing a few things which irked me for a while.
AND. Actions can be quite secure and reproducible... But it requires work, just like most NPM users run `npm install` instead of `npm ci` and never get reproducible builds either.
For extra security, add:
* Sha pinning
* fork actions
* limit actions to your own fork org
* only rely on script-based composite actions or sha pinned actions.
This requires some review work, but is quite doable.
This gives you reproducible builds, pinning, some level of integrity. And it's all enforcable by polity.
It it great? No. But when I compare it to other CI/CD tools, they are generally equally bad. Azure Pipelines? Yuk. TeamCity? Nope. Jenkins? Brrr?
Are there technically better solutions? Absolutely! But one of the powers of the actions platform is the ease at which people were able to grow the ecosystem. I've seen more innovation on GitHub Actions than ever on any other CI/CD patform, because anyone can contribute and because everything is possible :D.
@andrewnez Some feedback on the post:
Because of the way GitHub Actions resolves the version when using a "wildcard version", immutable releases add ZERO improvement. Action maintainers are required to force-push the major version tag every time they release a minor release anyway.
There is a funny extra behavior when it comes to tags *and* branches, when a v1 tag exists, and a v1 branch is pushed, the branch will take precedence over the tag. I've always considered this a security bug, but GitHub disagrees.
The reason there are so many unverified actions, is because GitHub won't verify individuals, only GitHub Organizations. So any action published to a personal namespace is by definition unverified. Even if the owner of the namespace is well known, a GitHub Star or MVP. Even some actions owned by GitHub employees are published to personal namespaces.
There are a few extras you can enable, especially on public repos, Automatic Dependency Submissions, Code Scanning for GitHub Actions etc which will add a layer of security to the environment.
Dependabot and RenovateBot offer features to auto-append a `# 4.1.7` version after the sha, adding both integrity and 'readability' to the reference.
You can control what Composite actions pull in, because you can set policy at the repo and org level controlling which actions (up to the sha if you want to) are allowed to run. And you can opt to not use composite actions at all. Since most actions will run scripts and often even download scripts and then run them, just making the action locked down, doesn't make the behavior locked down.
With automatic dependency submission, you can see all the actions and versions you rely on. But this requires you to opt in. And to get a cross repo overview you need a GitHub organization.
I've written a tool to try and build that tree.
@andrewnez Tool for submitting dependencies on actions and transitive dependencies for composite actions and callable workflows:
https://github.com/jessehouwing/actions-dependency-submission
@andrewnez Tool for ensuring a repo is actually doing its versioning correctly, cause many do not:
@andrewnez There is a long-time coming feature called Immutable Actions which supposedly solves almost all of these issues.
It stores the action contents in a docker image style package, publishes that to github packages as immutable filesystem snapshots.
You should be able to add metadata to those images, which should cover most of your other requirements. including SBOM support, integrity, pinning and more.
Unfortunately, it has taken forever to get released, as the tradeoff between flexibility and ease of use collides with integrity and security. The use cases for Actions are many and the needs are even more diverse.