Skip to content

Commit bfa8280

Browse files
committed
ci(spec-shape-gate): install objectui through its pinned-build directories, packed from this commit
objectui now overrides every @objectstack/* package it installs to file:node_modules/.cache/objectstack/<name>, a directory only its scripts/objectstack-pin.mjs build fills, so the gate's bare frozen install died on ENOENT there (exit 254) and every run reported exit 2. The gate now builds the packages those overrides name (read from objectui's package.json, --filter-prod closure) from this commit, packs them into those directories with OBJECTSTACK_ROOT set to this checkout, and then runs the frozen install. objectui compiles against all seven packages built here, not only the spec. The inject step stays: it still judges the spec's dependency ranges and proves every consumer resolves the injected copy, which the pin script does not (it compares dependency names only). Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp Co-authored-by: Claude <noreply@anthropic.com>
1 parent 725a5b1 commit bfa8280

1 file changed

Lines changed: 42 additions & 10 deletions

File tree

‎.github/workflows/spec-shape-gate.yml‎

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
name: Spec Shape Gate
22

33
# Compile the downstream consumer -- objectstack-ai/objectui at `main` -- against
4-
# `@objectstack/spec` built from THIS commit, and name the objectui file, the
5-
# objectstack commit and the owning lane when it does not compile.
4+
# `@objectstack/spec` (and every other `@objectstack/*` package it installs)
5+
# built from THIS commit, and name the objectui file, the objectstack commit and
6+
# the owning lane when it does not compile.
67
#
78
# ## The ruling this executes
89
#
@@ -205,16 +206,30 @@ jobs:
205206
- name: Self-test the gate script
206207
run: pnpm check:spec-shape-gate
207208

208-
# ── Build the spec from THIS commit, and PACK it ──────────────────────
209-
# `--filter @objectstack/spec...` installs the spec and its dependencies
210-
# only; `inject` later reads the dependencies this install resolved
209+
# ── Build what objectui installs, from THIS commit, and PACK the spec ──
210+
# objectui consumes every `@objectstack/*` package BY COMMIT: its root
211+
# `package.json` overrides each to `file:node_modules/.cache/objectstack/
212+
# <name>`, which its `scripts/objectstack-pin.mjs build` fills (below, with
213+
# OBJECTSTACK_ROOT naming this checkout). The names are read from those
214+
# overrides, the list the pin script packs; `--filter-prod` keeps the
215+
# closure to runtime edges as that script's own build does (`...` alone
216+
# would pull in the client's dev closure). The install brings the root's
217+
# toolchain too, and `inject` later reads the dependencies it resolved
211218
# (`packages/spec/node_modules`) to re-point a store sibling the packed
212219
# manifest's range refuses.
213-
- name: Install the spec's dependency closure
214-
run: pnpm install --frozen-lockfile --filter @objectstack/spec...
220+
- name: Install the closure of the @objectstack/* packages objectui installs by commit
221+
run: |
222+
set -euo pipefail
223+
filters=$(node -e '
224+
const m = JSON.parse(require("fs").readFileSync("objectui/package.json", "utf8"));
225+
const names = Object.keys(m.pnpm?.overrides ?? {}).filter((n) => n.startsWith("@objectstack/")).sort();
226+
if (names.length === 0) { console.error("objectui/package.json overrides no @objectstack/* package"); process.exit(2); }
227+
process.stdout.write(names.map((n) => `--filter-prod=${n}...`).join(" "));')
228+
echo "PINNED_FILTERS=$filters" >> "$GITHUB_ENV"
229+
pnpm install --frozen-lockfile $filters
215230
216-
- name: Build @objectstack/spec from this commit
217-
run: pnpm --filter @objectstack/spec build
231+
- name: Build them from this commit
232+
run: pnpm $PINNED_FILTERS run build
218233

219234
# What gets injected is what a RELEASE from this commit would ship -- the
220235
# `files` field's file set, not a working tree. `--ignore-scripts`
@@ -238,6 +253,20 @@ jobs:
238253
working-directory: objectui
239254
run: pnpm --version
240255

256+
# Packs every package built above into the directories objectui's
257+
# overrides name; without it the frozen install dies on ENOENT there. It
258+
# refuses (exit 1, its own `objectstack-pin` annotation) when a packed
259+
# manifest's dependency NAMES differ from what objectui's lockfile records:
260+
# the downstream owes a pin bump with its lockfile, and the report reads the
261+
# missing compile as exit 2. A changed peer, engines or dependency range is
262+
# not refused there -- a frozen install links it and exits 0 -- and the
263+
# spec's ranges stay `inject`'s to judge.
264+
- name: Pack this commit's @objectstack/* into objectui's pinned-build directories
265+
working-directory: objectui
266+
env:
267+
OBJECTSTACK_ROOT: ${{ github.workspace }}
268+
run: node scripts/objectstack-pin.mjs build
269+
241270
- name: Install objectui dependencies
242271
working-directory: objectui
243272
run: pnpm install --frozen-lockfile
@@ -254,7 +283,10 @@ jobs:
254283
# re-points a store sibling the packed manifest's range refuses at the
255284
# copy this tree's spec build resolved, and proves every workspace
256285
# consumer resolves the injected copy before returning. Nothing tracked
257-
# by git is touched in either checkout.
286+
# by git is touched in either checkout. The pinned build above already
287+
# installed this commit's spec (the same declaration files); what this
288+
# step still adds is that range judgement and the consumer proof, which
289+
# the pin script does not make (it compares dependency names only).
258290
- name: Inject the source-built spec into objectui's install
259291
env:
260292
UPSTREAM_SHA: ${{ steps.subjects.outputs.upstream }}

0 commit comments

Comments
 (0)