Skip to content

fix(ci): restore the pre-commit npm cache from a prefix key - #45909

Open
sadpandajoe wants to merge 2 commits into
masterfrom
ultraset-ci-pre-commit-job-intermittent-failures
Open

sadpandajoe wants to merge 2 commits into
masterfrom
ultraset-ci-pre-commit-job-intermittent-failures

Conversation

@sadpandajoe

@sadpandajoe sadpandajoe commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

SUMMARY

The pre-commit workflow's Setup Node.js step used setup-node's built-in cache: npm, which keys on the exact superset-frontend/package-lock.json hash with no fallback. Every push or PR that changes the lockfile (every Dependabot npm bump, for example) therefore starts npm ci with an empty cache and downloads ~2,850 tarballs, including xlsx from cdn.sheetjs.com rather than the npm registry. That makes the job fail whenever the registry or that CDN has a blip during the install. Between 2026-10-22 and 10-29 two pre-commit (current) runs failed this way and passed on re-run with no code change (40649064300: ECONNRESET after an 11-minute stall; 40679638770: 503 on cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz), and a master pre-commit (next) run timed out stalled in the same step (40678215774). No specific introducing change: this is how setup-node's cache has always keyed.

This replaces it with an actions/cache step on ~/.npm keyed npm-v1-<os>-<lockfile hash> with a npm-v1-<os>- restore prefix, gated on the same needs_node condition as Setup Node.js. After a lockfile change, npm ci starts from the most recent cache and fetches only the changed packages. This reduces the exposure; it does not remove it (the first run after merge, or after the cache is evicted, still installs cold). Not a retry, timeout or skip.

Measured locally (npm 11, npm ci --ignore-scripts, one-package lockfile change): 2 network GETs with a cache from the previous lockfile (the changed tarball plus a revalidation of the dom-to-image git dependency) vs 1,270 with an empty cache; xlsx served from cache.

CI on this PR is green on 1c3a7ad, but the npm steps are skipped here: needs_node is false for a workflow-only change. The cache gets measured after merge. The first master run seeds npm-v1-Linux-<hash>, and the next PR that changes the lockfile should restore from it via restore-keys.

TESTING INSTRUCTIONS

  1. On this PR, open the pre-commit (current) job: it passes, and Setup Node.js, Cache npm and Install Frontend Dependencies show as skipped (needs_node is false for a workflow-only change). After merge, the first master run's Cache npm step logs Cache not found for npm-v1-Linux-<hash> and saves the cache at the end.
  2. After merge, on the next PR that changes superset-frontend/package-lock.json, the Cache npm step logs Cache restored from key: npm-v1-Linux-<a different hash> (prefix fallback), and Install Frontend Dependencies finishes without re-downloading the unchanged packages.
  3. The cache only grows across lockfile changes; changing npm-v1 to npm-v2 resets it.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

🤖 Generated with Claude Code

sadpandajoe and others added 2 commits October 30, 2026 01:45
setup-node's built-in `cache: npm` keys on the exact
superset-frontend/package-lock.json hash and has no restore-keys
fallback, so any lockfile change (every dependency bump) runs `npm ci`
from an empty cache and re-downloads every tarball, including xlsx from
cdn.sheetjs.com rather than the npm registry. On 2026-10-28 that cold
path failed `pre-commit (current)` on two Dependabot PR runs
(40649064300: ECONNRESET after a 10-minute stall; 40679638770: E503 from
cdn.sheetjs.com), both green on re-run with no code change, and stalled
a master `pre-commit (next)` job into its timeout (40678215774).

Cache ~/.npm with actions/cache instead, keyed on the lockfile hash with
a prefix restore-key, so a lockfile change starts from the most recent
cache and only the changed packages are fetched. The step is gated on
needs_frontend, like the npm ci step it feeds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restore ~/.npm whenever Node is set up (needs_node), as setup-node's
`cache: npm` did, so a websocket-only change still gets a warm cache for
oxfmt-websocket's npx. needs_frontend implies needs_node, so the
frontend install is unaffected.

Reword the comment: an exact-key cache miss does not cause the failures,
it makes npm ci re-download every tarball and so exposes the install to
whatever registry/CDN outage is in progress; the prefix restore cuts the
downloads to the changed packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@netlify

netlify Bot commented Oct 30, 2026

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 1c3a7ad
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6ae517050f2cb01eff5adc57
😎 Deploy Preview https://deploy-preview-45909--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

# failed. Restoring from the prefix instead cuts the downloads to the
# changed packages.
- name: Cache npm
if: steps.changed_files.outputs.needs_node == 'true'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Websocket-only changes set needs_node but skip npm ci; this can save a cache with only npx data at the lockfile key, which later frontend runs cannot update.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Cache

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .github/workflows/pre-commit.yml
**Line:** 186:186
**Comment:**
	*Cache: Websocket-only changes set `needs_node` but skip `npm ci`; this can save a cache with only `npx` data at the lockfile key, which later frontend runs cannot update.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai-for-open-source

Copy link
Copy Markdown
Contributor

CodeAnt  CodeAnt PR Risk

🟢  Low Risk

  • The PR appears safe to merge, with a limited cache-efficiency concern.
  • Websocket-only runs can save an incomplete npm cache that later frontend runs cannot update for the same lockfile key, so those runs may still download dependencies.

Assessed commit: 1c3a7ad8e435

@hainenber

Copy link
Copy Markdown
Contributor

I'm hesitant to introduce npm/pypi caching in CI since cache poisoning attack is a known pattern that is also hard to mitigate.

@sadpandajoe

Copy link
Copy Markdown
Member Author

I'm hesitant to introduce npm/pypi caching in CI since cache poisoning attack is a known pattern that is also hard to mitigate.

thanks @hainenber for the insight, I'm not super attached to this PR so if we think it will cause more issues than it will help, more than happy to just close it out.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github_actions Pull requests that update GitHub Actions code size/S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants