I find the repeated deprecations on GitHub Actions frustrating to work with. One of the key goals of a build system is to be able to come back to a project after several years and just having the build work out of the box.
Yet with GHA I need to update actions/checkout@v2 to actions/checkout@vwhatever (or, what I'm doing now, actions/checkout@main because the actual API haven't actually changed) because... some Node version is "out of maintenance"?!
GHA is literally code execution as a service. Why would I care whether the Node runner has a security vulnerability?
NPM package security is a far bigger problem than some ephemeral invocation that probably isn't under PCI-DSS or HIPAA and doesn't serve content to the wild interwebs. Amount of caring should be nuanced for the use-case rather than projecting blanket, absolutist declarations.
I think GitHub Actions is missing a distinction between builds and automation.
When I build my software I care less about eliminating security vulnerabilities (after all, I need to build while updating to fix security issues), but also don't need, or ideally don't want any external access. A vulnerability in the build toolchain should be encoded into the artifacts but shouldn't necessarily prevent artifacts being generated.
However when I automate processes, like categorising bugs etc, I care a lot about eliminating security vulnerabilities because there is necessary external access, often write access, to my sensitive data.
GitHub considers these two things the same, but they're distinct use-cases with distinct approaches to maintenance, updating, and security.
Why both the pipe into sh and eval? The latter could handle all everything.
Couple more thoughts and unsolicited feedback from a quick eyeball:
- Use https://
- Wrap everything in a shell function to ensure that partial content is not executed.
- Wrap variable substitutions with "${OUTPUT_DIR}" to prevent arg splitting if they contain whitespace. Line 124, `rm -rf $OUT_DIR_INSTALL` is pretty scary if invoked with whitespace in OUT_DIR.
- Download nodejs tarball to temp directory and then extract them to prevent partial extraction
> Why would I care whether the Node runner has a security vulnerability?
I’m guessing they know you don’t care, but the big company customers cant have a CVE anywhere and won’t accept a EOL node version so they can check a box on something.
(I guess there’s also people with self hosted runners, who might be running them inside networks that aren’t segmented.)
> Why would I care whether the Node runner has a security vulnerability?
Because that "build" process has free access to your repo and potentially your organization. If your repo is also where you deploy from, then potentially deploying a vulnerable version of your software, live to your users.
If that's something you care about, then don't define your CI build in terms of GitHub Actions steps. Instead, call your build that takes care of using whichever version of Node you want in CI.
Real question here - why is `actions/checkout` dependent on Node at all? Seems like we wouldn't need to be on `actions/checkout@v5` at all if it was just written in, say, shell.
I don't expect to come back after x years and a build system to work. You're very much at the mercy of multiple components in your stack and environment. For example you could be on a Mac and 2 years ago you were using x64, but now you are on ARM64. Whole load of stuff just breaks from that alone.
Ops type here, something important to understand is Node is language the runner client uses so in particular, this is impactful for anyone building self-hosted runners and a will be a problem for anyone still writing Node 20 applications that just use self-hosted runner Node.
It's re-implementation of the GHA self-hosted runner in Go for self-hosted runners, based on the popular https://github.com/nektos/act for running GHA locally. Been using this for over a year now and it's been infinitely useful for CI on otherwise unsupported systems (e.g. freeBSD, openBSD in my case).
> Local Task Runner - I love make. However, I also hate repeating myself. With act, you can use the GitHub Actions defined in your .github/workflows/ to replace your Makefile!
This is ass backwards. Throwing out a tried and true build system in favor of a vendor-specific yaml format? Wtf? Just invoke make from your actions ffs.
I 100% get the purpose of the `act` tool, but I don't get why they wrote this sentence around `make`.
The tool is here to run GHA tasks locally, period. It's not a replacement for a Makefile.
And I agree with you: use `make` in your actions!
If I want to make sense of the sentence, the only thing I can think of is that, before making this tool, they were using a Makefile locally to replicate the content of their GHA tasks.
One annoying thing is you'd expect a company the size of microsoft to have an agreement for extended support. For example ubuntu 20.04 is no longer available as a runner on github actions as support ended in May of 2025, but extended support is available for a price until 2030. You'd think for a paid service they could pony up for a few licenses to keep things running, or provide an option for you to provide your own license.
> Node24 is incompatible with macOS 13.4 and lower versions.
...wait, really?
I have NodeJS 24 working all the way back on macOS 10.9 [1]. I realize official support is a very different thing, but I'm still surprised they can't do better than Ventura.
OTOH I've been moving from native NodeJS actions to packing them in a Docker container to separate code from compiled code.
If you wanted to use Typescript for your action you always had a 2 step process because GitHub Actions required you to pack dependencies with ncc or vite or webpack.
This packaged version was subsequently committed to the main branch.
Technically I could do a composite action where I compile the typescript on the fly, but that was fragile last time I tried it.
Yeah, strange to skip 22.
If GHA is mandating 24, while other vendors like Netlify currently max out at 22, there isn't even overlap in an LTS version I can deploy to both places? Just, wat.
Sadly docker actions can't be used in workflows that run on custom image (docker is not available in docker and making it available is an anti pattern) - they loose on their composability.
Yet with GHA I need to update actions/checkout@v2 to actions/checkout@vwhatever (or, what I'm doing now, actions/checkout@main because the actual API haven't actually changed) because... some Node version is "out of maintenance"?!
GHA is literally code execution as a service. Why would I care whether the Node runner has a security vulnerability?
"Why do I care if there is a potentially insecure code interpreter in my arbitrary code execution service?"
As someone where appsec is a component of my work in financial services, please believe you should care.
When I build my software I care less about eliminating security vulnerabilities (after all, I need to build while updating to fix security issues), but also don't need, or ideally don't want any external access. A vulnerability in the build toolchain should be encoded into the artifacts but shouldn't necessarily prevent artifacts being generated.
However when I automate processes, like categorising bugs etc, I care a lot about eliminating security vulnerabilities because there is necessary external access, often write access, to my sensitive data.
GitHub considers these two things the same, but they're distinct use-cases with distinct approaches to maintenance, updating, and security.
That's what I do and it's pretty stable: https://github.com/alshdavid-templates/siteforge/blob/main/....
Couple more thoughts and unsolicited feedback from a quick eyeball:
- Use https://
- Wrap everything in a shell function to ensure that partial content is not executed.
- Wrap variable substitutions with "${OUTPUT_DIR}" to prevent arg splitting if they contain whitespace. Line 124, `rm -rf $OUT_DIR_INSTALL` is pretty scary if invoked with whitespace in OUT_DIR.
- Download nodejs tarball to temp directory and then extract them to prevent partial extraction
I’m guessing they know you don’t care, but the big company customers cant have a CVE anywhere and won’t accept a EOL node version so they can check a box on something.
(I guess there’s also people with self hosted runners, who might be running them inside networks that aren’t segmented.)
Because that "build" process has free access to your repo and potentially your organization. If your repo is also where you deploy from, then potentially deploying a vulnerable version of your software, live to your users.
Just update your dependencies, it's not that hard. And it's even easier when you do it routinely as part of a deprecation planning.
As in, kills your old build code dead?
Then don't use Docker. You never know the image you are using will be outdated.
It's re-implementation of the GHA self-hosted runner in Go for self-hosted runners, based on the popular https://github.com/nektos/act for running GHA locally. Been using this for over a year now and it's been infinitely useful for CI on otherwise unsupported systems (e.g. freeBSD, openBSD in my case).
> Local Task Runner - I love make. However, I also hate repeating myself. With act, you can use the GitHub Actions defined in your .github/workflows/ to replace your Makefile!
This is ass backwards. Throwing out a tried and true build system in favor of a vendor-specific yaml format? Wtf? Just invoke make from your actions ffs.
The tool is here to run GHA tasks locally, period. It's not a replacement for a Makefile.
And I agree with you: use `make` in your actions!
If I want to make sense of the sentence, the only thing I can think of is that, before making this tool, they were using a Makefile locally to replicate the content of their GHA tasks.
Deleted Comment
...wait, really?
I have NodeJS 24 working all the way back on macOS 10.9 [1]. I realize official support is a very different thing, but I'm still surprised they can't do better than Ventura.
1: https://github.com/Wowfunhappy/Node-24-Mavericks/blob/master...
OTOH I've been moving from native NodeJS actions to packing them in a Docker container to separate code from compiled code.
If you wanted to use Typescript for your action you always had a 2 step process because GitHub Actions required you to pack dependencies with ncc or vite or webpack.
This packaged version was subsequently committed to the main branch.
Technically I could do a composite action where I compile the typescript on the fly, but that was fragile last time I tried it.
https://vercel.com/docs/functions/runtimes/node-js/node-js-v...