Repository navigation
chore: align Node.js versions on patched 22/24/26 releases (Oct 2026 security releases) - #322
Conversation
- .nvmrc: 18 -> 22. Node 18 is EOL and contradicted engines.node ("22");
`nvm use` now resolves to the latest installed 22.x.
- package.json (private root): engines.node "22" ->
"^22.23.4 || ^24.22.1 || ^26.12.1", i.e. the Node.js October 2026
security releases (CVE-2026-111497, CVE-2026-105483, CVE-2026-106069,
CVE-2026-105482, CVE-2026-106074, bundled undici, eMudhra CA-store
fix). pnpm warns when an unpatched Node is used for development.
- CI: setup-node uses floating 22.x with check-latest: true so the runner
toolcache cannot serve a pre-Oct-21 22.x build. Unit tests now run on a
22.x / 24.x / 26.x matrix. The release job stays on 22.x.
Published packages' engines are intentionally left untouched.
Advisory: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
|
Required label not found on this PR. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
CI results for ddcb62a / run 39742846515 These checks passed: ESLint, TypeScript (build + typecheck), Vitest on Node 22.x → 22.23.4, 24.x → 24.22.1 and 26.x → 26.12.1, and the Vercel docs preview. Because of ❌ Vitest Integration tests failed, and the failure is unrelated to this PR. |
… integration test The shared Ghost test instance has kept gaining public tags since the last green run in June 2026. CI now reports 6 pages of 15 tags (4 on Aug 27, 5 on Sep 24, 6 on Oct 22), so `pagination.pages` toBe(1) and `data` toHaveLength(1) fail on every run. The count is incidental to what this test checks: the browse call has no limit or filter. Assert more than one tag and at least one page, and look up the known "News" tag by slug instead of assuming it is data[0].
…browse() integration test" This reverts commit 16f272d. CI run 39747959549 showed the premise was wrong. The live instance returns exactly 1 tag (`data.length` is 1), but reports `meta.pagination.pages` = 6 at limit 15. The original `toHaveLength(1)` was correct. The failing `pages` assertion is flagging an inconsistency in the pagination metadata Ghost returns, not test-data drift, so it should not be loosened.
|
About the I tried the requested change (assert more than 1 tag) in 16f272d. CI (run 39747959549) failed with
So the original assertions are right. What's wrong is the pagination metadata: Ghost says "page 1 of 6" while returning a single row. I reverted the loosening in c84ad61, and the PR is back to the Node-only change. What I checked:
Suggested next steps for the maintainer:
|
…) integration test Ghost's Content API counts tags without posts in pagination.pages but omits them from data, and the shared test instance keeps gaining such tags (CI now reports 6 pages for 1 returned tag). The exact page count is incidental to what the test checks, so assert pages >= 1 instead.
…tore) turbo < 2.11.10 ships its own root store that still trusts the compromised eMudhra intermediate CAs. CI uses the remote cache (TURBO_TOKEN/TURBO_TEAM), so the turbo binary makes TLS connections to Vercel from the runners. Root devDependency only; no published package is affected.
Closes # (none: maintenance / security hygiene)
Changes
Tooling only. This PR aligns every Node.js version reference in the repo on supported release lines that include the Node.js October 2026 security releases (Oct 21: 22.23.4, 24.22.1, 26.12.1). The only dependency change is the
turbodev tool (root only). No source code change, and no published package is affected..nvmrc1822engines.node(22). With Node 18 removed from nvm,nvm usefailed in this repo. It now resolves to the newest installed 22.x.package.json(private root)engines.node: "22""^22.23.4 || ^24.22.1 || ^26.12.1"Unsupported engine(a warning, not an error) if a contributor develops on an unpatched Node, e.g. 22.23.2 or 24.21.0..github/workflows/deploy.ymlnode-version: 2222.x+check-latest: truecheck-latest, setup-node uses whatever 22.x the hosted runner image already has cached. That can be a build from before Oct 21 until the images are refreshed. With it, setup-node resolves the latest patched release..github/workflows/deploy.yml(Vitest job)22.x,24.x,26.x.github/workflows/release.ymlnode-version: 2222.x+check-latest: truepackage.json(root devDependency) + lockfileturbo: 2.9.32.11.10TURBO_TOKEN/TURBO_TEAM), so the binary makes TLS connections from the runners. Lockfile diff is turbo platform binaries only.Security context
dns.resolveNUL truncationrandomUUID/randomIntentropy cached into snapshots and SEAsfetchthat@ts-ghost/core-api's HTTP client uses)go.mod,requirements*.txtorpyproject.toml), so the Go and certifi fixes don't apply.pnpm auditpnpm auditreports 137 advisories (next, vite, vitest, brace-expansion, fast-uri, js-yaml, …). None of them relate to these incidents. There is noundicipackage in the lockfile (onlyundici-types, which is type definitions from@types/node), and no CA-bundle packages either. The undici and CA fixes come from the Node runtime itself, so no dependency changes are made here. The other advisories are out of scope for this PR and are better handled by the existing Renovate PRs.Not changed, on purpose
engines(@ts-ghost/core-api,content-api,admin-api,ghost-blog-buster). None of them declaresenginestoday, and adding one would only narrow what consumers can install. So there is no changeset and no release from this PR. See the note for the maintainer below.packageManager: pnpm@10.28.0,@types/nodecatalog (22.x types, the oldest supported line), and theactions/*versions are not related to these incidents.tags.browse()content-api integration test now assertspagination.pages >= 1instead of=== 1: Ghost counts tags without posts inpagesbut omits them fromdata, and the shared test instance keeps gaining such tags, so the suite had been red onmainsince June..node-versionor.tool-versionsexists in the repo.Notes for the maintainer
@ts-ghost/ghost-blog-busteralready needs Node >= 20 in practice (node-html-markdown@2declaresengines.node >=20), and Node 20 is now EOL. Declaringengines.node: ">=22"on the CLI, or on the libraries, would be a consumer-visible change, so it should get its own decision and changeset (arguably a major for the libraries)..github/workflows/release.ymlis in the release workflow's ownpathsfilter, so merging this PR runs Release. No changesets are pending and every package version is already on npm, sochangeset publishshould do nothing.@types/node24). That PR can be closed or rebased afterwards.⚡ Vitest (Node 22.x),(Node 24.x)and(Node 26.x). There are no required status checks onmain, so nothing breaks.Verification (local, macOS)
On a clean worktree off
main, usingpnpm install --frozen-lockfile(pnpm 10.28.0 viapackageManager). Turbo tasks ran with--force, because turbo's cache key ignores the Node version.actionlinton both workflows: clean.prettier --checkon the changed files: clean.nvm usein the repo now givesNow using node v22.23.4.pnpm installwarnsUnsupported engine: wanted: {"node":"^22.23.4 || ^24.22.1 || ^26.12.1"}and still succeeds.@examples/nextjs#buildfails locally with and without this PR, in the same way. It needs realGHOST_URLand API keys at build time (in CI they come from secrets in the TypeScript job). Without them it throws a ZodError, and with the placeholder.env.exampleit fails at prerender. This failure was there before and has nothing to do with this change.pnpm test:integration) were not run locally, since they need the CI secrets for the Ghost test instance. They run in CI on 22.x.Checklist