Skip to content

fix(renovate): pin npm <12 for lockfile regeneration (unblock dep PRs) - #3003

Open
rpapani wants to merge 3 commits into
mainfrom
fix/renovate-npm-constraint
Open

fix(renovate): pin npm <12 for lockfile regeneration (unblock dep PRs)#3003
rpapani wants to merge 3 commits into
mainfrom
fix/renovate-npm-constraint

Conversation

@rpapani

@rpapani rpapani commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Problem

Every Renovate dependency-update PR fails CI (ci/build, ci/it-postgres, type-check) — e.g. #2453, #2521, #2483 — and the failure is not in our code.

Root cause chain:

  1. The CI/Renovate runner defaults to npm 12 (node 24 ships npm 11, so npm 12 is an explicit upgrade in the fleet toolchain).
  2. Several internal @adobe/* packages pin engines.npm ">=10.9.0 <12.0.0" — e.g. @adobe/spacecat-helix-content-sdk@1.4.33 and @adobe/mysticat-shared-seo-client@1.8.0 (both direct deps; npm reports whichever it trips on first during resolution, so different PRs surface different package names). This is a shared internal engine convention, not one package's quirk.
  3. .npmrc has engine-strict=true, so Renovate's npm install (to regenerate package-lock.json) hard-fails EBADENGINE on that <12 cap and cannot write the lockfile.
  4. Renovate then bumps only package.json, leaving package-lock.json out of sync → every downstream CI job runs npm ci and fails with EUSAGE (Invalid: lock file's X does not satisfy Y).

main and human PRs are unaffected because they never regenerate the lockfile — and npm ci does not enforce engine-strict against the dependency tree the way npm install does (npm/cli#1219), so it stays green on npm 12.

Fix

Add a Renovate constraints pin so Renovate regenerates the lockfile with npm 11:

"constraints": { "npm": ">=10.9.0 <12.0.0" }

Renovate otherwise reads the root engines.npm (>=10.9.0, no ceiling) and picks npm 12; this overrides that for lockfile regeneration only. The range mirrors the actual engine requirement of the offending packages (floor and ceiling). Validated with renovate-config-validator ("Config validated successfully").

Why this over the alternatives:

  • Surgical & safeengine-strict stays on, root engines unchanged, and CI's npm ci stays on npm 12 (which already works — that's why main is green). Only Renovate's own artifact-update step uses npm 11.
  • Do NOT tighten root engines.npm to <12 — that would make npm ci on the npm-12 runner fail engine-strict on the root engine and break main.
  • packageManager in package.json would pin the toolchain for CI and every human dev too — far larger blast radius than needed.
  • Dropping engine-strict (what spacecat-audit-worker does — see below) also works, but removes the engine safety gate repo-wide.

Comparison with spacecat-audit-worker

audit-worker depends on the same @adobe/spacecat-helix-content-sdk@1.4.33 (same npm <12 cap) on the same npm-12 fleet CI, yet its Renovate PRs (#2842/#2816/#2780) merge fine and do update package-lock.json. The only difference: audit-worker has no engine-strict in .npmrc, so the npm-12 regen only warns on the content-sdk engine and proceeds. This PR keeps api-service's engine-strict gate and makes Renovate regenerate cleanly by feeding it a compatible npm — strictly safer than removing the gate.

Known trade-off (tool-version skew)

This intentionally makes Renovate author the lockfile with npm 11 while CI/humans consume it with npm 12. That's fine today because npm ci replays already-resolved lockfile entries. One narrow caveat for the record: this repo has a git dependency (git+ssh://…/mysticat-data-service) in the lockfile, and npm 12 changed allow-git/allow-remote defaults to "none"; if Renovate ever re-resolves that git dep under npm 11's more permissive defaults, the resulting entry might not be reproducible by a plain npm install on a default npm 12. Not a regression this PR introduces — noting it so it's on the record.

The real upstream fix is for the @adobe packages to widen engines.npm to allow ≥12, after which this constraint can be removed.

Impact

Once merged, Renovate re-runs and regenerates the lockfile (with npm 11) for the currently-stuck dep PRs (#2453 already merged via a hand-regenerated lock; #2521/#2483 and all future ones) — no more manual package-lock.json fixes.

Deployment

Config-only change (Renovate). No runtime/Lambda impact.

The CI runner defaults to npm 12, but @adobe/spacecat-helix-content-sdk pins
engines.npm ">=10.9.0 <12.0.0". With engine-strict=true in .npmrc, Renovate's
`npm install` to regenerate package-lock.json hard-fails EBADENGINE, so it
can only bump package.json -- leaving the lockfile out of sync and every
dep-bump PR failing CI's `npm ci` with EUSAGE (e.g. #2453, #2521, #2483).

Renovate reads the root engines.npm (">=10.9.0", no ceiling) and so uses
npm 12; this constraint overrides that to <12 for lockfile regeneration only.
Keeps engine-strict intact and leaves CI's `npm ci` on npm 12 (which works,
since npm ci only enforces the root package's engines, not the transitive
content-sdk one). Surgical: no change to .npmrc, engines, or the runner.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rpapani
rpapani requested a review from solaris007 August 5, 2026 23:27
…iption

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

This PR will trigger a patch release when merged.

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…straint

Mirrors the actual documented requirement of the offending @adobe packages
(both a floor and a ceiling), instead of a bare <12.0.0 that could resolve to
an unexpectedly old npm. Validated with renovate-config-validator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant