Commit 48b1e35
* test(#431): policy-shell-pinning linter — RED baseline (37 violations on origin/next)
Adds scripts/workflow-policy.cjs: H1 shell-policy linter with POLICY map,
VIOLATION enum, matrix expansion, effective-shell resolution order, and
runPolicyLint({ workflowsDir }) entry point.
Adds tests/policy-shell-pinning.test.cjs: 8 tests (baseline + 6 synthetic
counter-tests). Synthetic tests 2–7 pass; baseline test is intentionally RED
(37 violations: 28 in test.yml, 9 in install-smoke.yml — all macos/windows
lanes using shell: bash instead of native zsh/pwsh).
Adds js-yaml@4.1.1 as devDependency for YAML parsing.
* fix(#431): switch ubuntu/windows lanes to native shells; extract bash-isms to Node
Remove all explicit shell: bash pins from ubuntu-only jobs (changes, lint-tests,
coverage, required-tests, smoke-unpacked) — ubuntu runner default is bash, which
is both H1-compliant and the runner default, making the pin redundant.
For the test and test-full mixed-OS jobs (ubuntu+windows, windows+macos):
- Move bash-ism steps to shell-agnostic Node scripts:
scripts/ci-guard-runner.cjs — RUNNER_ENVIRONMENT check
scripts/ci-rebase-check.cjs — git fetch+merge PR base branch
scripts/check-npm-integrity.cjs — Node port of check-npm-integrity.sh
scripts/ci-prepare-test-scope.cjs — write .ci-selected-tests.txt
scripts/ci-smoke-skip.cjs — set skip= output for full-only matrix entries
- Remove shell: bash from simple npm/node command steps (runner default applies)
This brings Windows violations from 19 to 0. Remaining 17 violations are all
MACOS_MISSING_EXPLICIT_ZSH in mixed-OS matrix jobs (test-full: windows+macos,
install-smoke smoke: ubuntu+macos) — these require job splitting to fix; see
BLOCKER in PR description.
* fix(#431): update workflow-shell-pinning test for H1 policy
The old test required all Windows-targeting npm steps to pin shell: bash
(to prevent pwsh stderr-swallow). Under H1, Windows runners must use
pwsh (native, no pin needed) — shell: bash on Windows is now the
violation, not the fix.
Update findViolations() to flag npm steps with effectiveShell === 'bash'
(rather than effectiveShell === null). Update synthetic tests to verify
the H1-inverted semantics: defaults.run.shell: bash on Windows is now 2
violations, not 0. Update test name and assertion messages to describe
the H1 constraint rather than the old missing-pin constraint.
* fix(#431): extend policy linter to resolve matrix.shell expressions
- expandRunsOn now captures all matrix.include row keys as realization
context (os, node-version, shell, full_only, etc.) instead of only os
- effectiveShell now accepts a realizationContext and resolves
${{ matrix.<key> }} expressions against it before checking policy
- Unresolvable matrix key in shell expression emits UNRESOLVABLE_MATRIX
- Add 3 new tests: positive (zsh+pwsh per row → 0 violations),
counter (bash in macOS row → WRONG_SHELL_FOR_OS), counter (missing
shell key → UNRESOLVABLE_MATRIX)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#431): apply matrix.shell pattern to test-full and smoke jobs (clears BLOCKER)
test-full job (test.yml):
- Add shell: pwsh/zsh per matrix.include row (windows-latest→pwsh,
macos-latest→zsh)
- Add job-level defaults.run.shell: ${{ matrix.shell }}
- No step-level shell pins existed to remove
smoke job (install-smoke.yml):
- Add shell: bash/zsh per matrix.include row (ubuntu→bash, macos→zsh)
- Add job-level defaults.run.shell: ${{ matrix.shell }}
- No step-level shell pins existed to remove
Policy linter now reports 0 violations across all workflow files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(#431): migrate .sh check scripts to .cjs; remove .sh originals
- Add scripts/check-env.cjs: Node.js port of check-env.sh with
identical exit codes (0/1/2), human-readable and --json output,
--help flag, and all 5 checks (node-version, npm-version,
lockfile-present, lockfile-sync, version-manager-pin)
- Migrate all callers:
- package.json check:env → node scripts/check-env.cjs
- package.json check:integrity → node scripts/check-npm-integrity.cjs
- scripts/ci-test-scope.cjs path strings → .cjs equivalents
- .github/workflows/release.yml rc+finalize jobs → node .cjs (drop chmod+x)
- .github/workflows/security-scan.yml → node .cjs (drop chmod+x)
- tests/check-env.test.cjs → spawn node process.execPath [.cjs]
- tests/npm-integrity-gate.test.cjs → spawn node process.execPath [.cjs]
- Delete scripts/check-env.sh and scripts/check-npm-integrity.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(#431): update doc references from .sh to .cjs
Update SECURITY.md and docs/contributing/bootstrap.md to reference the
canonical Node invocation instead of the removed bash scripts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#431): use per-step shell:matrix.shell instead of defaults.run.shell (GHA compat)
GHA does not reliably resolve matrix expressions inside defaults.run.shell.
Per-step shell: always resolves correctly. Removed the defaults.run.shell block
from the test-full job (test.yml) and the smoke job (install-smoke.yml), and
added shell: \${{ matrix.shell }} directly on every run: step in both jobs.
Codex finding: defaults.run.shell with matrix expressions is not a
GHA-supported pattern; per-step shell: is the safe form.
* fix(#431): policy linter validates every matrix.include row independently
Removed runner-label-only dedup from expandRunsOn() in workflow-policy.cjs.
The prior guard (if !realizations.find(r => r.runner === runner)) collapsed
two macos-latest rows with different node-version/shell contexts into one,
hiding the second row's policy violation.
Each matrix.include row is a distinct CI realization with its own context;
validating it twice is harmless but skipping it causes false negatives.
Added counter-test (Test 8) in tests/policy-shell-pinning.test.cjs:
two macos-latest rows (shell:zsh compliant + shell:bash violation) must
produce exactly one WRONG_SHELL_FOR_OS violation on the second row.
* fix(#431): remove dedup-by-runner in Cartesian matrix.<key> expansion (Codex round 3)
The base-list path in expandRunsOn (matrix.<key> arrays, e.g. matrix.os)
previously guarded each push with `if (!realizations.find(r => r.runner === runner))`,
collapsing duplicate runner values into a single realization and hiding policy
violations on later rows of a Cartesian matrix.
Remove the guard unconditionally; each entry in the base-list array now produces
its own realization, matching the same fix already applied to the matrix.include path.
Add counter-test "Cartesian matrix os × shell — dedup must not collapse rows by
runner alone": matrix.os: [macos-latest, macos-latest] + shell: ${{ matrix.shell }}
now yields 2 realizations (not 1). Documents that Cartesian cross-product expansion
(carrying all keys into realization context) is a separate follow-up; current violations
are UNRESOLVABLE_MATRIX pending that work.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#431): remove 60s timeout regression on npm ci --dry-run (parity with check-env.sh)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(#431): ci-rebase-check.cjs — return truthy sentinel on success (Codex round 4)
run() used execFileSync with stdio:'inherit', which returns null on success.
Caller checked `result !== null`, always false → every successful fetch fell
through to "failed after 3 attempts" exit-1 path.
Fix: run() now returns true on success, false on failure.
Update caller from `result !== null` to `if (result)`.
Adds tests/ci-rebase-check.test.cjs (5 tests) covering the sentinel contract
and a local-bare-remote integration smoke that verifies the full fetch+merge
path exits 0 when fetch succeeds.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: CI Rebase Check <ci@gsd-redux>
1 parent a5eceb1 commit 48b1e35
23 files changed
Lines changed: 2060 additions & 955 deletions
File tree
- .github/workflows
- docs/contributing
- scripts
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
| 67 | + | |
67 | 68 | | |
68 | 69 | | |
69 | 70 | | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| 75 | + | |
73 | 76 | | |
74 | 77 | | |
75 | 78 | | |
76 | 79 | | |
77 | | - | |
78 | 80 | | |
79 | 81 | | |
80 | 82 | | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
| 83 | + | |
| 84 | + | |
87 | 85 | | |
88 | 86 | | |
89 | 87 | | |
| |||
102 | 100 | | |
103 | 101 | | |
104 | 102 | | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
| 103 | + | |
| 104 | + | |
119 | 105 | | |
120 | 106 | | |
121 | 107 | | |
| |||
126 | 112 | | |
127 | 113 | | |
128 | 114 | | |
| 115 | + | |
129 | 116 | | |
130 | 117 | | |
131 | 118 | | |
132 | 119 | | |
133 | 120 | | |
134 | | - | |
| 121 | + | |
135 | 122 | | |
136 | 123 | | |
137 | 124 | | |
| |||
141 | 128 | | |
142 | 129 | | |
143 | 130 | | |
144 | | - | |
| 131 | + | |
145 | 132 | | |
146 | 133 | | |
147 | 134 | | |
148 | 135 | | |
149 | 136 | | |
150 | 137 | | |
151 | 138 | | |
152 | | - | |
153 | 139 | | |
154 | 140 | | |
155 | 141 | | |
| 142 | + | |
156 | 143 | | |
157 | 144 | | |
158 | 145 | | |
| |||
170 | 157 | | |
171 | 158 | | |
172 | 159 | | |
173 | | - | |
| 160 | + | |
174 | 161 | | |
175 | 162 | | |
176 | 163 | | |
| |||
184 | 171 | | |
185 | 172 | | |
186 | 173 | | |
187 | | - | |
| 174 | + | |
188 | 175 | | |
189 | 176 | | |
190 | 177 | | |
| |||
193 | 180 | | |
194 | 181 | | |
195 | 182 | | |
196 | | - | |
| 183 | + | |
197 | 184 | | |
198 | 185 | | |
199 | 186 | | |
| |||
226 | 213 | | |
227 | 214 | | |
228 | 215 | | |
229 | | - | |
230 | | - | |
231 | | - | |
232 | | - | |
233 | | - | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
| 216 | + | |
243 | 217 | | |
244 | 218 | | |
245 | 219 | | |
| |||
251 | 225 | | |
252 | 226 | | |
253 | 227 | | |
254 | | - | |
255 | 228 | | |
256 | 229 | | |
257 | 230 | | |
258 | 231 | | |
259 | 232 | | |
260 | 233 | | |
261 | | - | |
262 | 234 | | |
263 | 235 | | |
264 | 236 | | |
| |||
268 | 240 | | |
269 | 241 | | |
270 | 242 | | |
271 | | - | |
272 | 243 | | |
273 | 244 | | |
274 | 245 | | |
| |||
280 | 251 | | |
281 | 252 | | |
282 | 253 | | |
283 | | - | |
284 | 254 | | |
285 | 255 | | |
286 | 256 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
189 | 189 | | |
190 | 190 | | |
191 | 191 | | |
192 | | - | |
193 | | - | |
| 192 | + | |
194 | 193 | | |
195 | 194 | | |
196 | 195 | | |
| |||
321 | 320 | | |
322 | 321 | | |
323 | 322 | | |
324 | | - | |
325 | | - | |
| 323 | + | |
326 | 324 | | |
327 | 325 | | |
328 | 326 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
47 | | - | |
48 | | - | |
| 46 | + | |
49 | 47 | | |
50 | 48 | | |
51 | 49 | | |
| |||
0 commit comments