Cache Node and the uv binary in CI #420

Merged
robbertbos merged 1 commit from ci-cache-node into main 2026-09-23 21:02:23 +00:00
Owner

A cache hit means CI downloads neither Node nor uv.

  • Node (4 jobs): actions/cache keeps ${{ runner.tool_cache }}/node under node-24-<os>. On a hit, setup-node finds Node 24 locally and makes no network call. This is the download that failed frontend-test on #416.
  • uv binary (3 jobs): the tarball is cached under uv-dist-<UV_SHA256>. sha256sum -c still runs on every job, cached or not, so the fail-closed pin is unchanged. A Renovate bump changes the sha and with it the key.

How long an entry lasts. Per the runner's own cache server (act/artifactcache/caches.go in forgejo/runner): unused for 7 days, deleted; 30 days after creation, always deleted; the same key saved again keeps only the newest. So a new Node 24 patch release arrives within a month without a date in the key. The cache lives on the runner host.

Not cached, on purpose. apt-get install postgresql and Playwright's --with-deps come from the Ubuntu mirrors, and caching apt packages is fragile. npm packages, Playwright browsers, uv packages and pre-commit envs were already cached.

To check on the first run. Whether Forgejo fills runner.tool_cache: the "Cache Node" step logs the path it saves. The first run is a cache miss and still downloads once.

A cache hit means CI downloads neither Node nor uv. - **Node** (4 jobs): `actions/cache` keeps `${{ runner.tool_cache }}/node` under `node-24-<os>`. On a hit, `setup-node` finds Node 24 locally and makes no network call. This is the download that failed `frontend-test` on #416. - **uv binary** (3 jobs): the tarball is cached under `uv-dist-<UV_SHA256>`. `sha256sum -c` still runs on every job, cached or not, so the fail-closed pin is unchanged. A Renovate bump changes the sha and with it the key. **How long an entry lasts.** Per the runner's own cache server (`act/artifactcache/caches.go` in forgejo/runner): unused for 7 days, deleted; 30 days after creation, always deleted; the same key saved again keeps only the newest. So a new Node 24 patch release arrives within a month without a date in the key. The cache lives on the runner host. **Not cached, on purpose.** `apt-get install postgresql` and Playwright's `--with-deps` come from the Ubuntu mirrors, and caching apt packages is fragile. npm packages, Playwright browsers, uv packages and pre-commit envs were already cached. **To check on the first run.** Whether Forgejo fills `runner.tool_cache`: the "Cache Node" step logs the path it saves. The first run is a cache miss and still downloads once.
Cache Node and the uv binary in CI
Some checks failed
CI / release-scripts (pull_request) Successful in 10s
security-scan / SBOM (trivy) (pull_request) Successful in 9s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 15s
security-scan / Python SAST (bandit) (pull_request) Successful in 22s
security-scan / JS SCA (npm audit) (pull_request) Successful in 34s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 41s
test-build / build (backend) (pull_request) Successful in 1m7s
CI / frontend-test (pull_request) Successful in 1m15s
test-build / build (frontend) (pull_request) Successful in 1m16s
test-build / build (pull_request) Successful in 0s
CI / pre-commit (pull_request) Successful in 2m49s
CI / backend-test (pull_request) Has been cancelled
CI / e2e (pull_request) Has been cancelled
b78fdf273a
setup-node downloaded Node on every run, asking the GitHub API first;
the shared runner IP hits its anonymous rate limit and the fallback
download failed ("API rate limit exceeded", then a TLS disconnect in
frontend-test). The Node tool cache is now kept with actions/cache,
keyed per month so a new patch release still arrives, and setup-node
finds it without any network call.

The uv tarball is cached under its pinned sha256 as the key. The
sha256 check still runs on every job, cached or not, so the
fail-closed anchor is unchanged.
robbertbos force-pushed ci-cache-node from b78fdf273a
Some checks failed
CI / release-scripts (pull_request) Successful in 10s
security-scan / SBOM (trivy) (pull_request) Successful in 9s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 15s
security-scan / Python SAST (bandit) (pull_request) Successful in 22s
security-scan / JS SCA (npm audit) (pull_request) Successful in 34s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 41s
test-build / build (backend) (pull_request) Successful in 1m7s
CI / frontend-test (pull_request) Successful in 1m15s
test-build / build (frontend) (pull_request) Successful in 1m16s
test-build / build (pull_request) Successful in 0s
CI / pre-commit (pull_request) Successful in 2m49s
CI / backend-test (pull_request) Has been cancelled
CI / e2e (pull_request) Has been cancelled
to 78bf61d59d
All checks were successful
CI / release-scripts (pull_request) Successful in 11s
security-scan / SBOM (trivy) (pull_request) Successful in 11s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 17s
security-scan / Python SAST (bandit) (pull_request) Successful in 23s
security-scan / JS SCA (npm audit) (pull_request) Successful in 35s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 40s
test-build / build (backend) (pull_request) Successful in 1m12s
CI / pre-commit (pull_request) Successful in 1m15s
test-build / build (frontend) (pull_request) Successful in 1m21s
test-build / build (pull_request) Successful in 0s
CI / frontend-test (pull_request) Successful in 1m23s
CI / backend-test (pull_request) Successful in 4m11s
CI / e2e (pull_request) Successful in 7m20s
2026-09-23 20:30:44 +00:00
Compare
robbertbos force-pushed ci-cache-node from 78bf61d59d
All checks were successful
CI / release-scripts (pull_request) Successful in 11s
security-scan / SBOM (trivy) (pull_request) Successful in 11s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 17s
security-scan / Python SAST (bandit) (pull_request) Successful in 23s
security-scan / JS SCA (npm audit) (pull_request) Successful in 35s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 40s
test-build / build (backend) (pull_request) Successful in 1m12s
CI / pre-commit (pull_request) Successful in 1m15s
test-build / build (frontend) (pull_request) Successful in 1m21s
test-build / build (pull_request) Successful in 0s
CI / frontend-test (pull_request) Successful in 1m23s
CI / backend-test (pull_request) Successful in 4m11s
CI / e2e (pull_request) Successful in 7m20s
to 38d44ea35a
Some checks failed
security-scan / SBOM (trivy) (pull_request) Successful in 16s
CI / release-scripts (pull_request) Successful in 17s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 27s
security-scan / Python SAST (bandit) (pull_request) Successful in 32s
security-scan / JS SCA (npm audit) (pull_request) Successful in 40s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 56s
test-build / build (frontend) (pull_request) Successful in 2m1s
test-build / build (backend) (pull_request) Successful in 2m1s
test-build / build (pull_request) Successful in 0s
CI / pre-commit (pull_request) Successful in 2m11s
CI / frontend-test (pull_request) Successful in 1m58s
CI / e2e (pull_request) Successful in 7m45s
CI / backend-test (pull_request) Has been cancelled
2026-09-23 20:44:11 +00:00
Compare
robbertbos scheduled this pull request to auto merge when all checks succeed 2026-09-23 20:50:13 +00:00
robbertbos force-pushed ci-cache-node from 38d44ea35a
Some checks failed
security-scan / SBOM (trivy) (pull_request) Successful in 16s
CI / release-scripts (pull_request) Successful in 17s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 27s
security-scan / Python SAST (bandit) (pull_request) Successful in 32s
security-scan / JS SCA (npm audit) (pull_request) Successful in 40s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 56s
test-build / build (frontend) (pull_request) Successful in 2m1s
test-build / build (backend) (pull_request) Successful in 2m1s
test-build / build (pull_request) Successful in 0s
CI / pre-commit (pull_request) Successful in 2m11s
CI / frontend-test (pull_request) Successful in 1m58s
CI / e2e (pull_request) Successful in 7m45s
CI / backend-test (pull_request) Has been cancelled
to 8f016ada6a
All checks were successful
CI / release-scripts (pull_request) Successful in 10s
security-scan / SBOM (trivy) (pull_request) Successful in 11s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 16s
security-scan / JS SCA (npm audit) (pull_request) Successful in 16s
security-scan / Python SAST (bandit) (pull_request) Successful in 24s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 41s
test-build / build (frontend) (pull_request) Successful in 1m5s
CI / pre-commit (pull_request) Successful in 1m7s
CI / frontend-test (pull_request) Successful in 1m8s
test-build / build (backend) (pull_request) Successful in 1m8s
test-build / build (pull_request) Successful in 0s
CI / backend-test (pull_request) Successful in 4m16s
CI / e2e (pull_request) Successful in 6m21s
tag-release / release (push) Successful in 7s
publish-and-stage / decide (push) Successful in 8s
CI / release-scripts (push) Successful in 14s
security-scan / SBOM (trivy) (push) Successful in 13s
security-scan / Filesystem scan (trivy fs) (push) Successful in 21s
security-scan / JS SCA (npm audit) (push) Successful in 22s
security-scan / Python SAST (bandit) (push) Successful in 26s
security-scan / Python SCA (pip-audit) (push) Successful in 43s
CI / frontend-test (push) Successful in 1m27s
publish-and-stage / build (frontend) (push) Successful in 1m20s
CI / pre-commit (push) Successful in 1m35s
publish-and-stage / build (backend) (push) Successful in 1m27s
publish-and-stage / build (push) Successful in 0s
publish-and-stage / deploy-staging (push) Successful in 2m10s
CI / backend-test (push) Successful in 4m22s
CI / e2e (push) Successful in 7m17s
2026-09-23 20:56:00 +00:00
Compare
robbertbos deleted branch ci-cache-node 2026-09-23 21:02:23 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
robbertbos/waggle!420
No description provided.