Skip to content

feat: dual foreground wait adapters — shell baseline + qualified characterization + frozen lifecycle strategies #280

feat: dual foreground wait adapters — shell baseline + qualified characterization + frozen lifecycle strategies

feat: dual foreground wait adapters — shell baseline + qualified characterization + frozen lifecycle strategies #280

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
name: ${{ matrix.os }} / Node ${{ matrix.node }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [22.13.0, lts/*]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
- run: npm ci
- name: Enforce LF line endings
run: npm run check:line-endings
- run: npm run check
env:
# Every shared runner can exceed the suite's exact local budgets
# under cold caches and parallel load (ceiling-scale receipt scans
# measured past 5 s on ubuntu and macos, not only windows), so the
# timeout multiplier applies uniformly.
ZCODE_TEST_TIMEOUT_MULTIPLIER: '3'
- name: Clean packed production install and Node 22.13 native binding smoke
run: node --test tests/integration/package-install.test.mjs
- name: Production lockfile native binding smoke
shell: bash
run: |
# The test suite spawns real fake-ZCode broker daemons from this
# checkout (node <repo>/scripts/zcode-broker.mjs), and every daemon
# loads the repo's node_modules/fs-native-extensions .node via
# scripts/lib/fs.mjs. A broker whose registered sessions/owners never
# settle never fires its idle shutdown, so it outlives the whole job
# (run 34364385782: both Windows jobs still held the .node past the
# old 35s retry and post-job cleanup terminated 3 orphan node
# processes). Windows forbids unlinking a loaded module, so an
# in-repo `npm ci` — which unlinks the repo's node_modules — EPERMs
# there no matter how long it waits. The smoke therefore runs in a
# throwaway export of the same commit (git archive, so no ref
# reachability questions on detached PR merge checkouts): it verifies
# the exact committed npm-shrinkwrap.json, installs prod-only from
# scratch, and no step ever unlinks the repo's node_modules.
smoke=$(mktemp -d)
git archive "$GITHUB_SHA" | tar -x -C "$smoke"
cd "$smoke"
npm ci --omit=dev
node -e "const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),lock=require('fs-native-extensions');const dir=fs.mkdtempSync(path.join(os.tmpdir(),'zcode-lock-'));const file=fs.openSync(path.join(dir,'smoke.lock'),'a+');if(!lock.tryLock(file))throw new Error('native lock unavailable');lock.unlock(file);fs.closeSync(file);fs.rmSync(dir,{recursive:true});"