| … | … | @@ -18,20 +18,6 @@ steps: |
| 18 | 18 | run: npm install --production |
| 19 | 19 | timeout: 300 |
| 20 | 20 | |
| 21 | | # Tests run BEFORE vendoring, and that ordering is load-bearing in a way that is not obvious: |
| 22 | | # `npm install brittle` RE-RESOLVES the tree and deletes hand-vendored directories (it reported |
| 23 | | # "removed 1194 packages" doing exactly that), so anything vendored earlier is gone by publish |
| 24 | | # time. pgh publish catches it — "declared file: dependencies did not resolve into the closure" |
| 25 | | # — but only after the whole build. The suites use fakes and import no sibling, so they have no |
| 26 | | # reason to run late. |
| 27 | | # |
| 28 | | # brittle is a devDependency and `npm install --production` skips it, so brittle-bare is not on |
| 29 | | # disk (npx then 404s — it is a bin from brittle, not its own package). Install transiently and |
| 30 | | # prune, so the tree pgh publish content-addresses is the production closure with no test deps. |
| 31 | | - name: tests (offline) |
| 32 | | run: npm install --no-save --no-audit --no-fund brittle && npx brittle-bare test/*.test.js && npm prune --production |
| 33 | | timeout: 240 |
| 34 | | |
| 35 | 21 | # Vendor LAST — after every npm operation, immediately before the guard and publish. A vendored |
| 36 | 22 | # sibling is copied from the WORKING TREE, so whatever is checked out on the build machine ships |
| 37 | 23 | # to the fleet, reviewed or not. Refuse unless each sibling HEAD is reachable from some hosted |
| … | … | @@ -90,6 +76,42 @@ steps: |
| 90 | 76 | exit $rc |
| 91 | 77 | timeout: 60 |
| 92 | 78 | |
| 79 | # Tests run AFTER vendoring, against the exact tree that is about to be published. |
| 80 | # |
| 81 | # ⛔ They used to run BEFORE vendoring, on the claim that "the suites use fakes and import no |
| 82 | # sibling". That stopped being true: the suites import anproto, favela-peer and favela-peer's test |
| 83 | # helpers, which in the git-archive checkout are dangling file: symlinks until the vendor step. So |
| 84 | # every build failed here (MODULE_NOT_FOUND: anproto), and a failed build records no version. That |
| 85 | # is why no CI build of ap-bridge landed between 2026-08-18 and 2026-10-12. Found by dry-running |
| 86 | # these steps on a git-archive export. |
| 87 | # |
| 88 | # ⛔ AND npm MUST NOT TOUCH THIS TREE NOW. `npm install brittle` re-resolves and deletes |
| 89 | # hand-vendored directories (it reported "removed 1194 packages"). So brittle is installed into a |
| 90 | # SEPARATE prefix, only the packages this tree lacks are copied in, the suite runs with the TREE'S |
| 91 | # copy of brittle (brittle-bare runs tests in-process, so runner and tests must share one instance), |
| 92 | # and exactly those added packages are removed again. The published closure is byte-for-byte what |
| 93 | # it was before this step. The version is the devDependency's range, not whatever is latest. |
| 94 | - name: tests (offline, against the vendored closure) |
| 95 | run: | |
| 96 | B=$(mktemp -d) |
| 97 | RANGE=$(node -p 'require("./package.json").devDependencies.brittle') |
| 98 | npm install --prefix "$B" --no-audit --no-fund --no-save "brittle@$RANGE" >/dev/null 2>&1 || { echo "could not install brittle@$RANGE"; exit 1; } |
| 99 | ADDED="" |
| 100 | for p in $(cd "$B/node_modules" && ls -A | grep -v -E '^\.'); do |
| 101 | case "$p" in |
| 102 | @*) for q in $(ls -A "$B/node_modules/$p"); do |
| 103 | if [ ! -e "node_modules/$p/$q" ]; then mkdir -p "node_modules/$p" && cp -r "$B/node_modules/$p/$q" "node_modules/$p/$q" && ADDED="$ADDED $p/$q"; fi |
| 104 | done ;; |
| 105 | *) if [ ! -e "node_modules/$p" ]; then cp -r "$B/node_modules/$p" "node_modules/$p" && ADDED="$ADDED $p"; fi ;; |
| 106 | esac |
| 107 | done |
| 108 | echo "overlaid for the test run only:$ADDED" |
| 109 | bare node_modules/brittle/bin/bare.js test/*.test.js; rc=$? |
| 110 | for p in $ADDED; do rm -rf "node_modules/$p"; done |
| 111 | rm -rf "$B" |
| 112 | exit $rc |
| 113 | timeout: 300 |
| 114 | |
| 93 | 115 | - name: pgh publish (content-addressed -> installable app) |
| 94 | 116 | run: pgh publish . --accept-conflict "automated CI publish; dep version-splits inherited from per-app lockfiles across the pgh ecosystem" |
| 95 | 117 | timeout: 300 |