Skip to content

ci(windows): run the unit suite on windows-latest (Git Bash)#100

Merged
CodeWithJuber merged 9 commits into
masterfrom
claude/parallel-solving-3dc0ji
Jul 20, 2026
Merged

ci(windows): run the unit suite on windows-latest (Git Bash)#100
CodeWithJuber merged 9 commits into
masterfrom
claude/parallel-solving-3dc0ji

Conversation

@CodeWithJuber

Copy link
Copy Markdown
Owner

What & why

Closes the last documented CI TODO — Windows coverage. Adds a Test (Windows / Git Bash) job to ci.yml that runs the unit suite on windows-latest. The suite does a lot of path work and the guards are bash, so this is where Windows-specific \-vs-/, tmpdir, and line-ending issues surface.

Runs node --test directly under Git Bash rather than npm test, because npm's Windows script-shell is cmd, which would pass the literal test/*.test.js glob unexpanded.

This is an iterative PR. The suite has never run on Windows, so the first run is expected to surface failures. I'll fix portable bugs (real cross-platform defects) and platform-gate the genuinely Unix-only tests (the bash guard-hook tests — native Windows users run those via WSL) as CI reveals them, driving to green.

Risk & rollback

  • CI-only; no src/, no package impact. Rollback = revert.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KfCEnSJzSG914yyVesjjD6


Generated by Claude Code

claude added 9 commits July 19, 2026 20:07
Adds the deferred Windows coverage (the smoke.yml TODO). Runs `node --test`
directly under Git Bash so the test glob expands (npm's Windows script-shell is
cmd). First pass to surface Windows-specific path/env issues; genuinely Unix-only
tests (bash guard hooks) will be platform-gated as CI reveals them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KfCEnSJzSG914yyVesjjD6
Two moves in the Windows-CI loop: (1) `.gitattributes` now pins `*.sh` to LF so a
Windows checkout can't hand bash CRLF-corrupted guard/install scripts (the likely
cause of most of the 37 first-run failures); (2) the Windows job now prints the
failing test names + files so the remaining genuinely-Unix-only tests can be
platform-gated precisely instead of diagnosed through a truncated log.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KfCEnSJzSG914yyVesjjD6
…windows-latest

Makes the unit suite pass on Windows (Git Bash). Fixes genuine cross-platform
path bugs (separator normalization / file:// URL construction / temp-path
handling in atlas, imagine, init, scope, uivisual, util, build-pages, and the
secret-redact guard) so they're correct on Windows and no-ops on POSIX, and
platform-gates the tests that fundamentally require a Unix/bash environment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KfCEnSJzSG914yyVesjjD6
The dryRun() perFile attribution compared absolute realpath'd worktree
paths against repo-relative test descriptors, which never matched on
Windows (backslash separators, drive letters) and broke test 418. Match
by relative POSIX suffix instead — robust across Linux, macOS, and
Windows — and drop the now-unused realpathSync import.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On Windows `git worktree remove --force` can fail when a just-exited
node --test worker still holds a handle on the sandbox. The old order
(remove → prune → rm) then let `git worktree prune` run while the
directory still existed, so it re-registered the worktree; the later
rmSync deleted the directory, leaving git listing a phantom worktree and
failing the dryRun cleanup assertion (count===1) on windows-latest.

Reorder teardown to remove → rm → prune: pruning runs last, after the
directory is gone, so git's bookkeeping reconciles against disk. Correct
on every OS; unblocks the last Windows CI failure (test 418).

Also dump full TAP YAML diagnostic blocks in the Windows CI step so
future per-test failures surface their assertion detail, not just names.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Windows CI diagnostic showed red.perFile coming back undefined: the
attribution abstained. Two Windows-specific causes: node --test emits
CRLF, so a stray \r on the `location:` line broke the parse; and any
single unmatchable `not ok` block flipped the whole map to omitted.

Since dryRun runs `node --test` on EXACTLY the requested files, every
real failure belongs to one of them. Rework attribution to: split on
CRLF-or-LF, match each failure block's location by POSIX suffix then
basename, skip location-less noise blocks, and abstain only when the
suite reported failures that pinned to no file at all. Robust on Linux,
macOS, and Windows. Closes the last PR #100 Windows failure (test 418).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion

dependabot #91 bumped gitleaks/gitleaks-action v2→v3, whose breaking
update requires a paid GITLEAKS_LICENSE for org-associated accounts and
HARD-FAILS when its license-validation server is unreachable ("License
key validation will be enforced") — turning the secret-scan gate red on
master and every PR for reasons unrelated to the code.

Replace the action with the pinned gitleaks binary (8.21.2). `gitleaks
detect` walks the full commit history (fetch-depth:0) exactly as before,
with no network license dependency, so the gate stays deterministic and
blocking. set -euo pipefail keeps it fail-closed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…suite

Running the gitleaks binary (prior commit) surfaced 2 findings the
licensed action never reached — it was erroring on license validation
before scanning, so the gate was effectively blind. Both are false
positives: synthetic PEM private-key literals in test/secrets.test.js,
the suite whose whole job is to assert forge redacts secret-shaped
strings. They are committed, so a full-history scan always matches them.

Add test/secrets.test.js to the .gitleaks.toml path allowlist (alongside
the existing bibliography-key exceptions); every other path stays fully
scanned. Verified locally: gitleaks 8.21.2 → 'no leaks found', exit 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@CodeWithJuber
CodeWithJuber marked this pull request as ready for review July 20, 2026 00:36
@CodeWithJuber
CodeWithJuber merged commit 9cde0ee into master Jul 20, 2026
11 of 12 checks passed
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.

2 participants