DEV Community

Samson
Samson

Posted on Edited on

How to check whether your CI is still running a dead Node version

Every green badge is a promise that your tests ran. The file behind it gets written once, at the moment someone is trying to ship, and then rarely re-read. I re-read 65 of them.

I pulled .github/workflows/*.yml from 30 of the most-downloaded npm packages. Thirteen of those 65 files execute at least one end-of-life Node somewhere. Node 18 stopped getting patches in April 2025. Node 20 stopped in April 2026.

Caveat first, because it changes the number: some of this is deliberate. node-semver tests back to Node 10, and validator.js back to Node 8, because those libraries promise to run on old runtimes. An old matrix entry is the feature working. The rot is the other kind, an old runtime nobody chose to keep.

Two files are that kind, and neither is a small package.

node-fetch (~142M downloads a week) runs its tests on ["12.20.0", "14.13.1", "16.0.0"] -- all three end-of-life -- and its ci.yml excludes node: "12.22.3" on Windows and macOS:

exclude:
  - os: windows-latest
    node: "12.22.3"
  - os: macOS-latest
    node: "12.22.3"
Enter fullscreen mode Exit fullscreen mode

There is no 12.22.3 in that matrix. The exclude cannot match anything. It is a leftover from a matrix that used to exist, kept because the badge stayed green.

rrule (~2.2M downloads a week) runs the same five yarn test lines under different locales, and the one cell that runs the heavier suite is Tokyo:

- run: LANG=jp_JP TZ=Asia/Tokyo yarn test-ci
Enter fullscreen mode Exit fullscreen mode

jp_JP is not a locale. Japanese is ja_JP. So the single job running the bigger suite has been running it under an invalid locale, and the badge has been green for years.

Both files still call actions/checkout@v2 and actions/setup-node@v2. The current major is v7.

A badge reports that steps exited 0. It never reports which runtime, which action version, or whether an exclude still matches a row that exists. Green gets read as "this file is current."

I wrote a script that does this read for any public repo (no token needed for a handful): ci_truth.py.

Or name a repo and I will do it by hand: one verified find from the real files, free. Full pass is $25. samson-7@ilands.app

Top comments (0)