Skip to content

ci: add unit test gate for scripts - #1226

Open
castrojo wants to merge 3 commits into
mainfrom
clanker/add-ci-test-gate-942
Open

ci: add unit test gate for scripts#1226
castrojo wants to merge 3 commits into
mainfrom
clanker/add-ci-test-gate-942

Conversation

@castrojo

Copy link
Copy Markdown
Contributor

Summary

Adds a CI test workflow running npm test on PRs and pushes that touch scripts/, package.json, or package-lock files.

Closes #942

Jorge Castro and others added 2 commits September 11, 2026 13:57
Hive-Task-Id: doc-942
Audit of the new gate found two defects that would keep it red:

- actions/setup-node@5fda3b95... does not exist upstream (GitHub
  reports no commit for the SHA), so every run would fail at job
  setup. Pin the real v7.0.0 commit 82076278... that every other
  workflow in this repository already uses.
- Add merge_group so the gate can run where merges actually land;
  this repository uses the merge queue and pages.yml already
  triggers on merge_group.
- The suite was not hermetic in a clean checkout: PortalContributors
  imports static/data/portal-contributors.json (gitignored generated
  output) at module scope, and the test shims read it with an
  unguarded readFileSync, so 5 portal tests failed with ENOENT on a
  fresh actions/checkout. A missing @site JSON now resolves to
  { unavailable: true }, the data contract the components already
  implement, matching the fixture-data direction of 4a50351.

Verified: node v24.18.1, node --test "scripts/**/*.test.js" passes
925/925 both with and without the gitignored static/data files;
actionlint 1.7.7 clean; eslint and prettier clean on touched files.

Refs #942

Assisted-by: Kimi K3 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo

Copy link
Copy Markdown
Contributor Author

Final-review audit (K3) found two defects that would have kept this gate red; fixed in 49c3719 on this branch:

  1. Bogus action pin (fatal): actions/setup-node@5fda3b95a4ea91299a34e894583c3862153e4b97 does not exist upstream — gh api repos/actions/setup-node/commits/5fda3b95... returns "No commit found for SHA". Every run would fail at job setup. Repinned to the real v7.0.0 (820762786026740c76f36085b0efc47a31fe5020, verified via gh api repos/actions/setup-node/git/refs/tags/v7.0.0), the same pin every other workflow here uses.
  2. Suite not hermetic in a clean checkout (fatal): PortalContributors.tsx:6 imports @site/static/data/portal-contributors.json (gitignored, generated) at module scope; the three portal test shims read it with an unguarded readFileSync. Simulated actions/checkout state (the three gitignored data files removed): 5 tests fail, 920/925. The shims now resolve a missing @site JSON to { unavailable: true } — the data contract these components already implement. Clean-tree and dirty-tree runs both pass 925/925 on node v24.18.1.
  3. Also added merge_group: (one line, pages.yml precedent) so the gate can run where merges actually land — this repo merges via the queue.

actionlint 1.7.7 clean; eslint/prettier clean on touched files. Workflow remains a sensitive path — maintainer review before merge per AGENTS.md.

The require shim convention for module-scope @site/static/data/*.json
imports now has a stated rule: a missing generated file resolves to
{ unavailable: true } so the suite stays green in a clean CI checkout.
Same PR as the shim fix, per the skill-improvement mandate.

Refs #942

Assisted-by: Kimi K3 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The hermetic-shim fix is the valuable part here — I hit that exact failure independently. Three notes on the workflow.

The shim fix is real

Before touching any PR, I ran the suite on unmodified main at 0b052ae:

$ npm run test:coverage
ℹ tests 925
ℹ pass 920
ℹ fail 5

test at scripts/portal-static-render.test.js:204:1
✖ PortalContributors renders graceful unavailable fallback when data is unavailable or empty
  Error: ENOENT: no such file or directory, open '.../static/data/portal-contributors.json'

All 5 failures were that one missing gitignored artifact, across portal-page-loading, portal-prototype-page and portal-static-render. Seeding echo '[]' > static/data/portal-contributors.json gives 925 / 925 / 0. So this is not hypothetical — a clean checkout fails the suite today, and the fs.existsSync(target) ? ... : { unavailable: true } change is exactly right. The docs/skills/component-testing.md note is a good capture of the rule.

1. npm ci --legacy-peer-deps is unnecessary and masks real conflicts

pages.yml uses plain npm ci, and plain npm ci works on this tree:

$ npm ci
(exit 0)

I also ran it cleanly on the #1215 merge, which adds a new dependency. Please drop --legacy-peer-deps so the two workflows agree and a genuine peer conflict fails loudly rather than being silently downgraded.

2. The gate is weaker than the one in pages.yml

This runs npm test, which is:

"test": "node --test \"scripts/**/*.test.js\""

pages.yml already runs npm run test:coverage, which is the same suite plus --test-coverage-lines=60 --test-coverage-functions=60 --test-coverage-branches=60. So a PR can pass this new required-looking gate while regressing coverage below the threshold, and only find out in the Pages build. Using npm run test:coverage here makes the fast gate the authoritative one.

3. The paths: filter excludes the source the tests cover

    paths:
      - "scripts/**"
      - "package.json"
      - "package-lock.json"
      - ".github/workflows/test.yml"

But the portal tests this PR just repaired live in scripts/ and load components from src/:

// scripts/portal-static-render.test.js
const rel = id.slice("@site/".length);   // resolves .ts/.tsx out of src/

So a PR that only touches src/components/portal/*.tsx#1211 and #1228 among the currently open ones — does not trigger this workflow, even though scripts/portal-*.test.js is precisely what would catch a break. Adding src/** to both paths: blocks closes that hole.

None of this is blocking; the workflow is correct as far as it goes and Run scripts unit tests is green on this PR.


Generated by Claude Code

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.

[quality] Add CI test gate for scripts/ unit tests

2 participants