Skip to content

refactor(ci-scope): replace classifier with thin shim (PR 2/3)#507

Merged
blove merged 3 commits into
mainfrom
claude/ci-scope-shim-rewrite
May 21, 2026
Merged

refactor(ci-scope): replace classifier with thin shim (PR 2/3)#507
blove merged 3 commits into
mainfrom
claude/ci-scope-shim-rewrite

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented May 21, 2026

Summary

PR 2 of 3 for the ci-scope thin-shim migration. Rewrites `scripts/ci-scope.mjs` to delegate project ownership to `nx show projects --affected` and read `scope:*` tags off affected projects.

Changes

  • `apps/cockpit/project.json`: adds `namedInputs.deploymentConfig` (11 paths: vercel.*.json, deploy scripts, capability-registry.ts) + references it in `build.inputs`.
  • `apps/website/project.json`: adds `namedInputs.deploymentConfig` with `vercel.json` + same target inputs pattern.
  • `scripts/ci-scope.mjs`: 340 LOC → 120 LOC. Drops `applyProjectScope`, `applyFallbackPathScope`, `discoverProjects`, `ownsPath`. Keeps `GLOBAL_CI_FILES` short-circuit.
  • `scripts/ci-scope.spec.mjs`: full rewrite. 13 tests inject synthetic affected-project arrays directly.

Wins

  • ~80 LOC of hand-maintained `applyProjectScope` rules → ~10 LOC of tag-driven `classifyFromAffected`.
  • ~50 LOC of `applyFallbackPathScope` file-path rules → per-project `namedInputs` as Nx-native data.
  • ~30 LOC of project-graph walking → replaced by `nx affected` (project graph is authoritative).
  • New contributors discover scope membership via project tags, not a centralized classifier.

Smoke-test (pre-flight, local)

Verified that modifying `vercel.cockpit.json` correctly marks `cockpit` as affected via `nx show projects --affected`. Without this, the new shim would underfire on those file changes.

Risk note

This PR's own CI run is the integration test. If the new shim misclassifies (e.g., emits `cockpit_e2e=false` when it should be true), the cockpit-e2e job won't fire correctly. Do not admin-merge — wait for the `CI scope` job's logs, verify the scope output against the PR's diff before merging.

Follow-up

PR 3 adds a drift-guard assertion to `cockpit-e2e-wiring.spec.ts` (every cap project has expected `scope:*` tags).

See spec: `docs/superpowers/specs/2026-05-21-ci-scope-thin-shim-design.md`.

🤖 Generated with Claude Code

PR 2 of 3 for the ci-scope thin-shim migration. PR 1 (#503) added
scope:* tags to 87 project.json files; this PR makes ci-scope.mjs
actually read them via `nx show projects --affected`.

apps/cockpit + apps/website: namedInputs.deploymentConfig
- Per-project namedInputs declare which non-project files affect each
  project: vercel.*.json, scripts/deploy-smoke.ts, capability-registry.ts,
  etc. on apps/cockpit; vercel.json on apps/website.
- Referenced from each project's build target inputs so nx considers
  them when computing affected.
- Replaces ~50 LOC of applyFallbackPathScope rules with Nx-native data.
- Smoke-verified: `nx show projects --affected` correctly marks
  `cockpit` as affected when vercel.cockpit.json changes.

scripts/ci-scope.mjs: 340 LOC → 120 LOC.
- applyProjectScope (~80 LOC of project-walking rules) → replaced by
  ~10-LOC tag-driven classifyFromAffected reading from
  `nx show projects --affected --json`.
- applyFallbackPathScope (~50 LOC of file-path rules) → replaced by
  the namedInputs above.
- discoverProjects walk (~30 LOC of filesystem traversal) → gone.
- GLOBAL_CI_FILES short-circuit (.github/workflows/ci.yml etc.) kept.
- Backward-compatible CLI: --base/--head/--output/--event=push.

scripts/ci-scope.spec.mjs: full rewrite.
- Tests inject synthetic affectedProjects arrays with tag arrays directly
  (no more synthetic workspace+ownsPath fixtures).
- 13 tests across 5 describe blocks: short-circuit, publishable lib
  broadcast, cockpit cap angular/python, fallback paths via namedInputs,
  tag isolation (non-scope tags + unknown scope keys ignored).

Backward-compatible workflow gating: same scope booleans emit for the
same file changes. Jobs still truly skip (no per-job fast-pass cost).

This PR's own CI run is the integration test. DO NOT admin-merge — if
the new shim misclassifies, its own gates fire wrong. Verify scope
output in the CI scope job's logs before merging.

See docs/superpowers/specs/2026-05-21-ci-scope-thin-shim-design.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
threadplane Ready Ready Preview, Comment May 21, 2026 5:18pm

Request Review

CI runs `node --test scripts/ci-scope.spec.mjs` directly (no vitest
installed at the ci-scope job's pre-npm-ci stage). My PR 2 rewrite
imported `describe, it, expect` from 'vitest' and used Chai-style
matchers; CI errored with ERR_MODULE_NOT_FOUND on 'vitest'.

Rewrite spec to use Node's built-in test runner:
- import { describe, it } from 'node:test'
- import assert from 'node:assert/strict'
- expect(x).toBe(y) → assert.equal(x, y)
- expect(x).toEqual(y) → assert.deepEqual(x, y)

All 13 tests pass via `node --test`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ected

PR 2's ci-scope.mjs rewrite delegates project ownership to `nx show
projects --affected --json`. The CI scope job previously had no node
setup or npm install (just `actions/checkout` + `node --test`), so
the new shim errored with "Could not find Nx modules" at runtime.

Add setup-node@v6 (node 22, cache: npm) + `npm ci` before the
classifier test and the scope-detection step. Tax: ~15-30s warm cache,
~60s cold cache, on every CI run. This is the one-time-per-PR cost of
using nx's project graph as the source of truth instead of a hand-
maintained classifier walk.

Comment block in the ci.yml explains the rationale so reviewers
understand why setup got more elaborate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@blove blove merged commit 7a29adc into main May 21, 2026
37 of 38 checks passed
blove added a commit that referenced this pull request May 21, 2026
#509)

PR 3 of 3 for the ci-scope thin-shim migration. PR 1 (#503) added
scope:* tags to every CI-participating project; PR 2 (#507) rewrote
ci-scope.mjs to read them via `nx show projects --affected --json`.
This drift-guard asserts every cockpit cap project (angular + python
under cockpit/<product>/<topic>/) declares the expected tags:

- scope:cockpit-e2e + scope:cockpit-examples on every cap project.
- scope:cockpit-smoke on python caps that have a smoke target.

Closes the silent-failure mode: future contributors adding a new cap
can't forget the tags — the test names which project + which tag is
missing.

Excludes cockpit/ag-ui/* (no python sibling; different tag rules).

See spec: docs/superpowers/specs/2026-05-21-ci-scope-thin-shim-design.md.

Co-authored-by: Claude Opus 4.7 (1M context) <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