|
64 | 64 | # that nor an over-eager expiry shows up as an error anywhere. |
65 | 65 | - run: npm run probe:cookie-jar |
66 | 66 |
|
| 67 | + # --- the same gate, on the OLDEST Node package.json admits ----------------- |
| 68 | + # Every other job pins `node-version: 22`, and `.nvmrc` says `22`. Both resolve |
| 69 | + # to the newest 22.x, so before this job existed NO MACHINE ANYWHERE ran the |
| 70 | + # regime `engines.node` promises to support — not CI, not a contributor using |
| 71 | + # nvm. That is not a hypothetical gap: `npm run dev` shipped broken on |
| 72 | + # 22.0-22.17 twice, behind three rounds of green gates, because Node only |
| 73 | + # strips TypeScript types unprompted from 22.18 and every runner had it. |
| 74 | + # |
| 75 | + # Pinned to the exact floor rather than a range, so that raising `engines.node` |
| 76 | + # without raising this line leaves an untested version admitted, and lowering |
| 77 | + # it without lowering this line is a promise nothing checks. The two are meant |
| 78 | + # to be edited together; scripts/spike-install-latency.mjs asserts they match. |
| 79 | + # |
| 80 | + # Cheap by construction: it is the Wasm-free offline tier, the same one |
| 81 | + # `toolchain-gate` runs, so it costs a second checkout and about a minute. |
| 82 | + # Without the crates, run-spikes skips the `needsWasm` spikes — which is what |
| 83 | + # keeps this job honest about Node versions rather than about OpenSSL: the |
| 84 | + # `constants` spike compares the host's bundled OpenSSL and zlib against the |
| 85 | + # VM's and legitimately differs on any Node but the newest. |
| 86 | + toolchain-floor: |
| 87 | + if: github.event_name != 'schedule' |
| 88 | + runs-on: ubuntu-latest |
| 89 | + steps: |
| 90 | + - uses: actions/checkout@v7 |
| 91 | + - uses: actions/setup-node@v7 |
| 92 | + with: |
| 93 | + # Keep in step with `engines.node`. |
| 94 | + node-version: "22.15.0" |
| 95 | + # Named separately from the tier below so that the failure this job exists |
| 96 | + # to catch reads as itself. Thirteen scripts import the studio's templates |
| 97 | + # out of a .ts file and two of them run on every `npm run dev`; when that |
| 98 | + # broke, the generators failed soft and the only visible symptom was a dev |
| 99 | + # server that was quietly slow. |
| 100 | + - name: the studio templates must import on the floor, not only on latest |
| 101 | + run: | |
| 102 | + node --input-type=module -e " |
| 103 | + const { loadShippedTemplates } = await import('./scripts/lib/shipped-templates.mjs'); |
| 104 | + const t = await loadShippedTemplates(); |
| 105 | + if (!Array.isArray(t) || t.length === 0) throw new Error('loaded no templates'); |
| 106 | + console.log('loaded ' + t.length + ' templates on Node ' + process.versions.node); |
| 107 | + " |
| 108 | + - run: node scripts/run-spikes.mjs --offline |
| 109 | + |
| 110 | + # The corpus gate that installs each shipped lock in the VM lives in |
| 111 | + # `template-gate`, which is schedule/dispatch only because it needs the Rust |
| 112 | + # toolchain and an hour. That leaves merges unguarded against the change most |
| 113 | + # likely to poison a lock: an edit to templates.ts, to the generator, or to |
| 114 | + # the kernel's alias table. RESOLVING all of them needs none of that — no |
| 115 | + # Wasm, no VM, ~35s — and resolution is where both guards run, so a template |
| 116 | + # that starts pulling in an aliased native is refused here rather than on the |
| 117 | + # deploy that ships it. It is not the in-VM gate and does not replace it; it |
| 118 | + # is the part of that gate which is cheap enough to block a merge. |
| 119 | + # |
| 120 | + # `--strict`, because producing them IS this job's subject. The cost is that a |
| 121 | + # registry outage reddens a PR — the same trade `template-gate` already makes |
| 122 | + # for the same command, against the alternative of hearing it from a nightly. |
| 123 | + lock-resolution-gate: |
| 124 | + if: github.event_name != 'schedule' |
| 125 | + runs-on: ubuntu-latest |
| 126 | + timeout-minutes: 15 |
| 127 | + steps: |
| 128 | + - uses: actions/checkout@v7 |
| 129 | + - uses: actions/setup-node@v7 |
| 130 | + with: |
| 131 | + node-version: 22 |
| 132 | + - name: every shipped lockfile must still resolve, and pass both guards |
| 133 | + run: npm run vendor:locks -- --strict |
| 134 | + |
67 | 135 | # SDK packaging + public-API contract guard (offline, no Wasm, no browser). |
68 | 136 | # Also regression-checks the shipped preview sw.js branding + examples/basic. |
69 | 137 | sdk-smoke: |
@@ -111,7 +179,7 @@ jobs: |
111 | 179 | # but missing here runs nowhere at all: skipped in toolchain-gate for want of |
112 | 180 | # the crates, and never selected in the only job that has them. |
113 | 181 | - name: offline spikes that need the Wasm VFS |
114 | | - run: node scripts/run-spikes.mjs --offline dep-cache bun http-binary-body http-response-bytes cookie-session fs-cp fs-errors worker-pool node-cli repl stack-traces readline watch child-stdin fs-metadata crypto-jwk zlib-brotli port-liveness constants diag-liveness fatal-errors net-close-order net-blocklist |
| 182 | + run: node scripts/run-spikes.mjs --offline dep-cache depcache-shipped seed-swc bun http-binary-body http-response-bytes cookie-session fs-cp fs-errors worker-pool node-cli repl stack-traces readline watch child-stdin fs-metadata crypto-jwk zlib-brotli port-liveness constants diag-liveness fatal-errors net-close-order net-blocklist |
115 | 183 | - run: npm run verify |
116 | 184 |
|
117 | 185 | # --- package-manager gate: the North Star, gated on its own ---------------- |
@@ -214,6 +282,23 @@ jobs: |
214 | 282 | # a bare `lit` also selects sqlite and pglite: this step was running two in-VM |
215 | 283 | # database spikes it does not name, on a job whose failures are supposed to mean |
216 | 284 | # "a shipped template stopped booting". Nine ran where seven were asked for. |
| 285 | + # There is deliberately no `vendor:locks` step here. It used to be one, and |
| 286 | + # a step is the wrong place for it: `spikes-net` runs the same lock-reading |
| 287 | + # spikes with no such step, so `vendor/locks/` was empty there and |
| 288 | + # `template-locks` died in 0.2s on the first missing file while the eight |
| 289 | + # template spikes silently installed from RANGES — two jobs exercising |
| 290 | + # different code paths for the same template, which is the one thing a |
| 291 | + # second job must not do. Provisioning now belongs to the spikes that need |
| 292 | + # it (`VENDORS.locks` in scripts/run-spikes.mjs), so every job that selects |
| 293 | + # one gets the locks, and a job added tomorrow cannot forget. |
| 294 | + # Every id in COVERAGE, installed in the VM from the lock the runner |
| 295 | + # provisions for it. This is the gate that made COVERAGE forty templates |
| 296 | + # instead of one: a spike per template would have been ~50 near-identical |
| 297 | + # files, so this is one spike driven over the list. It installs and checks |
| 298 | + # the tree is usable rather than booting a server — the step below is what |
| 299 | + # boots servers, for the eight frameworks it names. |
| 300 | + - name: every shipped lockfile must install into a usable tree |
| 301 | + run: node scripts/run-spikes.mjs --net template-locks$ |
217 | 302 | - name: framework templates must start their dev server |
218 | 303 | run: node scripts/run-spikes.mjs --net react$ preact$ lit$ solid$ vue$ svelte$ qwik$ ember$ |
219 | 304 | # The two the step above used to pick up by accident, kept blocking on purpose. |
|
0 commit comments