GitNexus/.github/workflows/ci-quality.yml
Gergő Magyar a348bc3957
fix(build): build the web UI from prepack, not from every npm ci (#3166)
* fix(build): build the web UI from prepack, not from every npm ci

gitnexus-web is a separate ~650-package tree (React, Vite, LangChain,
Mermaid). Because `prepare` built it, every `npm ci` in gitnexus/ also
installed and Vite-built a second product. On CI that install ran
uncached inside an execSync timeout, so a healthy-but-slow install was
SIGTERM'd mid-flight and surfaced as `spawnSync /bin/sh ETIMEDOUT` --
repeatedly killing node floor compat, a job that only import-links the
CLI dist and never needs the UI.

The UI is only needed inside the published tarball, so build it from
prepack instead. `npm run build` and `prepare` are now CLI-only; pass
--web (or npm run build:web) to include it. Jobs that pack or publish
install gitnexus-web in their own visible step, and the in-script
fallback install is untimed so a slow install can no longer be killed
halfway and reported as a build failure. The tsc/vite timeout default
goes 300s -> 600s so the remaining bounded steps have headroom.

Default build on this machine: 30s, no gitnexus-web work.

* fix(build): enforce web package artifact integrity

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(build): clarify web packaging helpers without changing behavior

Keep the same opt-in, fail-closed, and pack/publish preserve rules while
trimming comments, sharing the test harness, and reading index.html
directly instead of probing it first.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ci: skip prepare on typecheck so a cold shared install cannot cancel the job

quality/typecheck's 10-minute budget was spent on an uncached gitnexus-shared
npm install plus a full prepare tsc that tsc --noEmit does not need.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ci: stop typecheck-web from canceling before the npm cache can save

Hashing gitnexus-shared into the web cache key forced a cold 650-package
install; the 10-minute job then canceled and never wrote a warm cache.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ci: give format the same 10-minute budget as lint

A cold root npm ci already took 4m19s and canceled prettier at the 5-minute
cap. Lint does the same install and needed 7m41s on that run.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ci: stop installing TypeScript 7 just to compile gitnexus-shared

A dedicated npm ci in gitnexus-shared took 7 minutes to add two packages
(TypeScript 7's optional per-platform binaries) and cancelled typecheck,
Windows pack, and coverage shard 1. Compile shared with gitnexus's tsc.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address PR review feedback (#3166)

- Run tsc via execFileSync so the compiler path is never interpolated into a shell.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address PR review feedback (#3166)

- Run tsc as node typescript/bin/tsc so Windows never has to execFile a .cmd shim.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Launch tsc via node and lib/tsc.js on every OS.

The npm .bin/tsc shim is tsc.cmd on Windows, which execFileSync cannot spawn.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): lock eval containment against a dedicated shared npm ci

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 13:28:11 +01:00

94 lines
3.3 KiB
YAML

name: Quality Checks
on:
workflow_call:
permissions:
contents: read
jobs:
format:
runs-on: ubuntu-latest
# Same root npm ci as lint. A cold install already took 4m19s here and
# canceled prettier at the 5-minute job cap; lint needed 7m41s the same run.
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
- run: npm ci --ignore-scripts
- run: npx prettier --check .
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
- run: npm ci --ignore-scripts
- run: npx eslint .
typecheck:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# tsc --noEmit reads source + gitnexus-shared/dist. Skip prepare/postinstall
# so a cold shared install cannot eat the 10-minute budget on a second tsc.
- uses: ./.github/actions/setup-gitnexus
with:
lifecycle-scripts: 'false'
- run: npx tsc --noEmit
working-directory: gitnexus
typecheck-web:
runs-on: ubuntu-latest
# Cold gitnexus-web npm ci is several minutes (mermaid/langchain/playwright).
# A 10-minute cancel prevents setup-node from saving the cache, so the next
# run is cold again.
timeout-minutes: 15
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: ./.github/actions/setup-gitnexus-web
- run: npx tsc -b --noEmit
working-directory: gitnexus-web
# Enforces the convention documented in CONTRIBUTING.md → "GitHub Actions —
# Concurrency Convention":
# 1. Every entry-point (non-reusable) workflow declares a top-level
# `concurrency:` block.
# 2. Reusable workflows (`on: workflow_call` only) do NOT declare one —
# they inherit concurrency from the caller.
# 3. The concurrency group key starts with `${{ github.workflow }}` or
# the literal `CI-` prefix (the documented ci.yml exception for
# reusable-workflow-safe grouping).
# Reusability is detected by parsing each workflow's `on:` block, not an
# allowlist, so new reusable workflows never produce false positives.
workflow-convention:
name: Workflow concurrency convention
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Validate workflow concurrency convention
shell: bash
run: |
set -euo pipefail
python3 .github/scripts/check-workflow-concurrency.py .github/workflows