GitHub's changelog says Node 20 reaches end of life in April 2026, runners moved to Node 24 by default from 16 June 2026, and Node 20 is removed from runners on 23 September 2026. Actions that still declare Node 20 need an updated version, or they may fail.
What the changelog states
GitHub's deprecation notice for Node 20 on Actions runners went through several edits. Its latest editor note, dated 25 August 2026, sets the Node 20 removal date to 23 September 2026. Earlier notes moved the default switch to Node 24 to 16 June 2026. The page describes an opt-out environment variable that lets workflows keep using Node 20 only until the runner is upgraded and Node 20 is removed.
It also notes that Node 24 is incompatible with macOS 13.4 and lower, and that Node 24 lacks official ARM32 support, so self-hosted ARM32 runners are no longer supported after the Node 20 deprecation. For maintainers, it says to update actions to run on Node 24. For users, it says to update workflows to the latest versions of actions that run on Node 24.
Because the date moved more than once, do not rely on a screenshot or a forwarded message. Read the live page and record the date you read it. This is a good example of a lifecycle date that is itself unstable.
Why a CI runtime belongs in your dependency inventory
Each action you reference is code that runs with access to your repository, your tokens and often your deploy credentials. An action that is JavaScript-based runs on a Node runtime chosen by the runner. So two lifecycle questions apply:
- Is the action itself maintained?
- Does it run on a runtime that is still supported by the platform?
If either answer is no, the pipeline has an unmaintained component in a privileged position. See a contributor PR adds a new dependency for habits that also apply to actions.
How to find affected workflows
- List every workflow file under the workflows directory in each repository.
- Extract each uses line, with the action name and ref.
- For third-party actions, open the action's metadata file at the ref you use and read the runtime it declares.
- Mark any that declare Node 20 or older.
- Check whether a newer release declares Node 24, and test it.
For many repositories, script steps 1 and 2 and keep the output in your inventory. Pinning actions to a full commit hash makes step 3 repeatable, because the metadata you read is exactly what runs.
What to do with each finding
| Finding | Action |
|---|---|
| Newer version on Node 24 exists | Update and pin the new commit |
| No newer version, action maintained | Open an issue, note a date to recheck |
| No newer version, abandoned | Replace it or inline the few commands you need |
| Self-hosted ARM32 runner | Plan a different runner architecture |
When to fork an abandoned dependency applies if you decide to maintain a copy.
Try it yourself
Click through it at your own pace, or open it full screen. Look at where a check sits in the pull request flow, which is where a pipeline change should be reviewed too.
Where Safeguard fits
Safeguard's policies and gates apply checks at the pull request, and dependency scanning covers the packages your code uses. Treat the list of actions as part of the same inventory. The free scan is at gold.safeguard.sh/scan.
Quick check
Do I need to change anything if my workflows use only first-party actions?
Check that you use current versions. First-party actions are updated by their maintainers, but older pinned versions may still declare an old runtime.
Why pin to a commit hash?
A tag can move. A hash shows exactly which code ran and which runtime it declared.
Sources
Last reviewed: 19 October 2026.