fix(ci): remove npm cache from setup-node (act ignores cache-dependency-path) #20

Closed
opened 2026-08-07 18:16:04 +03:00 by slaid098 · 0 comments
Owner

Контекст

PR #16 (cache-dependency-path: package-lock.json для ci.yml) и PR #18 (то же для deploy.yml) влиты, но не решили проблему. Анализ логов:

  • ci.yml push (run id=135, success): Found in cache @ /opt/hostedtoolcache/node/22.23.2/x64 → cache restored → НЕ вычисляет ключ → до lstat eslint.config.mjs не дошёл → success. cache-dependency-path передан, но не использован (cache уже был).
  • deploy.yml push (run id=142, failure): cache отсутствует в /opt/hostedtoolcache → вычисляет ключ → lstat /root/.cache/act/.../eslint.config.mjs: no such file or directory → failure. cache-dependency-path: package-lock.json передан, но act игнорирует его — всё равно идёт к eslint.config.mjs.

Вывод: cache-dependency-path НЕ работает в act-эмуляции setup-node@v4 на Forgejo runner. Опция передаётся, но act при cache-miss вычисляет ключ через дефолтный path-finding (eslint.config.mjs), игнорируя custom path. ci.yml работает только потому что cache разогрет в /opt/hostedtoolcache — это nondeterministic, сломается при GC/новом контейнере.

Блокер: deploy.yml падает на каждом push — сайт не обновляется (PR #15 content не в проде).

Задача

  1. Убрать cache: "npm" и cache-dependency-path: "package-lock.json" из actions/setup-node@v4 в .forgejo/workflows/ci.yml (строки 18-19).
  2. Убрать cache: "npm" и cache-dependency-path: "package-lock.json" из actions/setup-node@v4 в .forgejo/workflows/deploy.yml (строки 18-19).
  3. Проверить: push на main → оба workflow success (ci.yml + deploy.yml). npm ci выполняется полностью (без cache restore), deterministic.

Почему Вариант A (без cache), а не B

  • Вариант B (cache-dependency-path) — не работает на act (доказано логами run id=142). Опция игнорируется при cache-miss.
  • Вариант A (убрать cache) — 100% надёжно. npm ci deterministic по package-lock.json, ~10-15с без cache. Замедление приемлемо для CI (качество важнее скорости).
  • Альтернатива (self-hosted runner вместо act) — инфра-решение, отдельная задача. Пока act — cache ненадёжен.

Контракты

  • ci.yml и deploy.yml остаются в .forgejo/workflows/.
  • Триггеры не меняются (ci: pull_request + push; deploy: push).
  • Steps не меняются (только параметр cache удалён).
  • node-version: "22" сохраняется.
  • Секреты deploy.yml не трогаются.

Инварианты

  • CI quality-gate (lint + typecheck + knip + test + build) — обязателен на PR и push.
  • Деплой на Vercel — обязателен на push.
  • npm ci deterministic — тот же результат всегда (без cache-nondeterminism).

Граничные случаи

  • npm ci без cache: ~10-15с (download + install). На 4 параллельных run — 4x нагрузка на npm registry. Приемлемо (npm registry handles это).
  • Если позже захотим cache — self-hosted runner с персистентным volume (не act per-container cache).

Влияние на связанные компоненты

  • .forgejo/workflows/ci.yml — убрать 2 строки.
  • .forgejo/workflows/deploy.yml — убрать 2 строки.
  • pipeline-status — после фикса оба workflow success на push.
  • Сайт slaid098.dev — обновится (PR #15 content в проде после успешного deploy).
  • Memory — обновить: cache-dependency-path НЕ работает на act, Вариант A — единственный надёжный.

Вне scope

  • Self-hosted runner (инфра-решение).
  • Разделение ci.yml на параллельные jobs.
  • Vercel CLI версия.

Критерии приемки

  • cache: "npm" и cache-dependency-path удалены из обоих workflow.
  • Push на main → ci.yml run → status=success (без cache, npm ci deterministic).
  • Push на main → deploy.yml run → status=success (деплой работает, сайт обновлён).
  • Логи: НЕТ lstat eslint.config.mjs (опция cache отсутствует, lstat не вызывается).
  • npm ci выполняется ~10-15с (без cache restore, но deterministic).
## Контекст PR #16 (`cache-dependency-path: package-lock.json` для ci.yml) и PR #18 (то же для deploy.yml) влиты, но **не решили проблему**. Анализ логов: - **ci.yml push (run id=135, success)**: `Found in cache @ /opt/hostedtoolcache/node/22.23.2/x64` → cache restored → НЕ вычисляет ключ → до `lstat eslint.config.mjs` не дошёл → success. `cache-dependency-path` передан, но не использован (cache уже был). - **deploy.yml push (run id=142, failure)**: cache отсутствует в `/opt/hostedtoolcache` → вычисляет ключ → `lstat /root/.cache/act/.../eslint.config.mjs: no such file or directory` → failure. `cache-dependency-path: package-lock.json` передан, но `act` **игнорирует** его — всё равно идёт к `eslint.config.mjs`. **Вывод**: `cache-dependency-path` НЕ работает в `act`-эмуляции `setup-node@v4` на Forgejo runner. Опция передаётся, но `act` при cache-miss вычисляет ключ через дефолтный path-finding (`eslint.config.mjs`), игнорируя custom path. ci.yml работает **только** потому что cache разогрет в `/opt/hostedtoolcache` — это nondeterministic, сломается при GC/новом контейнере. **Блокер**: deploy.yml падает на каждом push — сайт не обновляется (PR #15 content не в проде). ## Задача 1. Убрать `cache: "npm"` и `cache-dependency-path: "package-lock.json"` из `actions/setup-node@v4` в `.forgejo/workflows/ci.yml` (строки 18-19). 2. Убрать `cache: "npm"` и `cache-dependency-path: "package-lock.json"` из `actions/setup-node@v4` в `.forgejo/workflows/deploy.yml` (строки 18-19). 3. Проверить: push на main → оба workflow success (ci.yml + deploy.yml). `npm ci` выполняется полностью (без cache restore), deterministic. ## Почему Вариант A (без cache), а не B - **Вариант B (`cache-dependency-path`)** — не работает на `act` (доказано логами run id=142). Опция игнорируется при cache-miss. - **Вариант A (убрать cache)** — 100% надёжно. `npm ci` deterministic по `package-lock.json`, ~10-15с без cache. Замедление приемлемо для CI (качество важнее скорости). - **Альтернатива (self-hosted runner вместо `act`)** — инфра-решение, отдельная задача. Пока `act` — cache ненадёжен. ## Контракты - ci.yml и deploy.yml остаются в `.forgejo/workflows/`. - Триггеры не меняются (ci: pull_request + push; deploy: push). - Steps не меняются (только параметр `cache` удалён). - `node-version: "22"` сохраняется. - Секреты deploy.yml не трогаются. ## Инварианты - CI quality-gate (lint + typecheck + knip + test + build) — обязателен на PR и push. - Деплой на Vercel — обязателен на push. - `npm ci` deterministic — тот же результат всегда (без cache-nondeterminism). ## Граничные случаи - `npm ci` без cache: ~10-15с (download + install). На 4 параллельных run — 4x нагрузка на npm registry. Приемлемо (npm registry handles это). - Если позже захотим cache — self-hosted runner с персистентным volume (не `act` per-container cache). ## Влияние на связанные компоненты - `.forgejo/workflows/ci.yml` — убрать 2 строки. - `.forgejo/workflows/deploy.yml` — убрать 2 строки. - `pipeline-status` — после фикса оба workflow success на push. - Сайт slaid098.dev — обновится (PR #15 content в проде после успешного deploy). - Memory — обновить: `cache-dependency-path` НЕ работает на `act`, Вариант A — единственный надёжный. ## Вне scope - Self-hosted runner (инфра-решение). - Разделение ci.yml на параллельные jobs. - Vercel CLI версия. ## Критерии приемки - `cache: "npm"` и `cache-dependency-path` удалены из обоих workflow. - Push на main → ci.yml run → status=success (без cache, `npm ci` deterministic). - Push на main → deploy.yml run → status=success (деплой работает, сайт обновлён). - Логи: НЕТ `lstat eslint.config.mjs` (опция cache отсутствует, lstat не вызывается). - `npm ci` выполняется ~10-15с (без cache restore, но deterministic).
Sign in to join this conversation.
No labels
bug
performance
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
slaid098/slaid098-dev#20
No description provided.