Skip to content

Commit 127ee94

Browse files
os-zhuangclaude
andauthored
chore(build): decouple SDUI manifest + react-conformance ratchet from console build (#2492)
build-console.sh launched a headless browser (Playwright) to dump the public-tier SDUI manifest and ratchet ADR-0081 conformance. That made every `objectui:build` / `objectui:refresh` / `release` rebuild depend on a matching Playwright browser being installed — a freshly bumped objectui SHA crashes the rebuild with `browserType.launch: Executable doesn't exist`. The browser step never belonged on the build path: - It was already "best-effort, non-fatal" (gate falls back to parse-level). - In CI it never actually ran: both workflows install Playwright AFTER build-console.sh (release installs none), so the ratchet silently degraded every time. It only executed when a dev happened to have a matching browser. Move manifest generation + conformance ratchet into a dedicated on-demand script and keep build-console.sh single-purpose (rebuild console SPA + copy dist, no browser). - scripts/gen-sdui-manifest.sh (new): reuses the vendored .cache/objectui-<sha> tree; clear guidance when the tree is missing (run objectui:build) or the Playwright browser is missing; fails loud instead of silently degrading. - scripts/build-console.sh: drop the browser block, point to `pnpm sdui:manifest`. - package.json: add `sdui:manifest` script. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ef6d2e7 commit 127ee94

3 files changed

Lines changed: 87 additions & 35 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"docs:start": "pnpm --filter @objectstack/docs start",
2222
"os": "node packages/cli/bin/run.js",
2323
"objectui:build": "bash scripts/build-console.sh",
24+
"sdui:manifest": "bash scripts/gen-sdui-manifest.sh",
2425
"objectui:bump": "bash scripts/bump-objectui.sh",
2526
"objectui:refresh": "bash scripts/bump-objectui.sh && bash scripts/build-console.sh",
2627
"objectui:clean": "rm -rf packages/console/dist .cache/objectui-*",

scripts/build-console.sh

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -129,38 +129,10 @@ cp -R "$CONSOLE_DIST" "$TARGET"
129129
BYTES="$(du -sk "$TARGET" 2>/dev/null | awk '{print $1}')"
130130
echo "✓ @objectstack/console dist ready (${BYTES} KB) from objectui@${PINNED_SHA:0:12}"
131131

132-
# ADR-0080: generate the public-tier SDUI manifest from the just-built console's
133-
# registry so the framework os-build JSX gate can do full component/prop
134-
# validation. Best-effort and GUARDED: skips on a sha without the dump tooling,
135-
# and never fails the console build (the gate falls back to parse-level).
136-
DUMP_PAGE="${BUILD_ROOT}/apps/console/dev/manifest-dump.html"
137-
DUMP_SCRIPT="${BUILD_ROOT}/scripts/dump-public-manifest.mjs"
138-
if [[ -f "$DUMP_PAGE" && -f "$DUMP_SCRIPT" ]]; then
139-
echo "→ Generating SDUI public-tier manifest (ADR-0080)..."
140-
pushd "$BUILD_ROOT" > /dev/null
141-
pnpm --filter @object-ui/console exec vite dev --port 5180 > /tmp/sdui-dump-dev.log 2>&1 &
142-
DUMP_DEV_PID=$!
143-
for _ in $(seq 1 90); do curl -sf "http://localhost:5180/" > /dev/null 2>&1 && break; sleep 1; done
144-
if BASE_URL="http://localhost:5180" OUT="${TARGET}/sdui.manifest.json" node scripts/dump-public-manifest.mjs; then
145-
echo "✓ wrote ${TARGET}/sdui.manifest.json"
146-
# ADR-0081: ratchet the spec↔frontend react-block conformance against the
147-
# committed baseline while the freshly-dumped manifest is here for free. This
148-
# is the ONLY place the manifest exists, so it is the cheapest place to catch
149-
# NEW divergence (a component exposing an undocumented prop, or a block
150-
# vanishing). Warn-only — never fails the console build; run check:react-conformance
151-
# --strict locally to gate intentionally.
152-
if [[ -f "${FRAMEWORK_ROOT}/packages/spec/react-conformance.baseline.json" ]]; then
153-
echo "→ Ratcheting spec↔frontend react-block conformance (ADR-0081)..."
154-
( cd "${FRAMEWORK_ROOT}" && MANIFEST="${TARGET}/sdui.manifest.json" \
155-
pnpm --filter @objectstack/spec check:react-conformance \
156-
--baseline react-conformance.baseline.json ) || \
157-
echo "⚠ conformance ratchet reported new divergence (non-fatal) — see output above"
158-
fi
159-
else
160-
echo "⚠ manifest generation failed — os-build JSX gate falls back to parse-level (non-fatal)"
161-
fi
162-
kill "$DUMP_DEV_PID" 2>/dev/null || true
163-
popd > /dev/null
164-
else
165-
echo "ℹ manifest dump tooling not present at objectui@${PINNED_SHA:0:12} — skipping (bump .objectui-sha to >=96b1293 to enable full JSX validation)"
166-
fi
132+
# ADR-0080/0081: the public-tier SDUI manifest and the spec↔frontend react-block
133+
# conformance ratchet are intentionally NOT generated here — they require a real
134+
# browser (Playwright) to enumerate the console registry, and the console build
135+
# must not drag in a browser dependency. Regenerate them on demand instead:
136+
# pnpm sdui:manifest (see scripts/gen-sdui-manifest.sh)
137+
echo "ℹ SDUI manifest + conformance ratchet are decoupled from the console build."
138+
echo " Run 'pnpm sdui:manifest' on demand to regenerate (requires Playwright)."

scripts/gen-sdui-manifest.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env bash
2+
# ADR-0080/0081: generate the public-tier SDUI component manifest and ratchet the
3+
# spec↔frontend react-block conformance.
4+
#
5+
# This is deliberately SEPARATE from build-console.sh and is NOT part of the
6+
# default build. The console component registry is a browser app (plugin-map /
7+
# charts pull browser-only deps), so the only reliable way to enumerate it is to
8+
# load the built `manifest-dump.html` in a real browser and read
9+
# `window.__MANIFEST`. We do not want every console rebuild to drag in a
10+
# Playwright browser dependency, so this step is opt-in / on-demand:
11+
#
12+
# pnpm objectui:build # (re)build + vendor the console dist at .objectui-sha
13+
# pnpm sdui:manifest # then dump the manifest + ratchet conformance
14+
#
15+
# Requires a matching Playwright browser. If it complains the executable is
16+
# missing, install it:
17+
#
18+
# pnpm exec playwright install chromium-headless-shell
19+
#
20+
# Output: packages/console/dist/sdui.manifest.json (consumed by the os-build
21+
# JSX gate for full component/prop validation; absent -> gate falls back to
22+
# parse-level).
23+
24+
set -euo pipefail
25+
26+
FRAMEWORK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
27+
SHA_FILE="${FRAMEWORK_ROOT}/.objectui-sha"
28+
29+
if [[ ! -f "$SHA_FILE" ]]; then
30+
echo "${SHA_FILE} is missing — cannot determine which objectui commit to use."
31+
exit 1
32+
fi
33+
PINNED_SHA="$(tr -d '[:space:]' < "$SHA_FILE")"
34+
35+
BUILD_ROOT="${FRAMEWORK_ROOT}/.cache/objectui-${PINNED_SHA:0:12}"
36+
TARGET="${FRAMEWORK_ROOT}/packages/console/dist"
37+
DUMP_PAGE="${BUILD_ROOT}/apps/console/dev/manifest-dump.html"
38+
DUMP_SCRIPT="${BUILD_ROOT}/scripts/dump-public-manifest.mjs"
39+
40+
if [[ ! -d "$BUILD_ROOT" ]]; then
41+
echo "✗ objectui build tree not found at ${BUILD_ROOT}"
42+
echo " Run 'pnpm objectui:build' first to vendor the console at the pinned SHA."
43+
exit 1
44+
fi
45+
if [[ ! -f "$DUMP_PAGE" || ! -f "$DUMP_SCRIPT" ]]; then
46+
echo "ℹ manifest dump tooling not present at objectui@${PINNED_SHA:0:12} — nothing to do."
47+
echo " (bump .objectui-sha to >=96b1293 to enable full JSX validation)"
48+
exit 0
49+
fi
50+
51+
echo "→ Generating SDUI public-tier manifest (ADR-0080) from objectui@${PINNED_SHA:0:12}..."
52+
pushd "$BUILD_ROOT" > /dev/null
53+
pnpm --filter @object-ui/console exec vite dev --port 5180 > /tmp/sdui-dump-dev.log 2>&1 &
54+
DUMP_DEV_PID=$!
55+
trap 'kill "$DUMP_DEV_PID" 2>/dev/null || true' EXIT
56+
for _ in $(seq 1 90); do curl -sf "http://localhost:5180/" > /dev/null 2>&1 && break; sleep 1; done
57+
58+
if BASE_URL="http://localhost:5180" OUT="${TARGET}/sdui.manifest.json" node scripts/dump-public-manifest.mjs; then
59+
echo "✓ wrote ${TARGET}/sdui.manifest.json"
60+
else
61+
status=$?
62+
echo "✗ manifest generation failed (exit ${status})."
63+
echo " If Playwright reported a missing browser, install it and retry:"
64+
echo " pnpm exec playwright install chromium-headless-shell"
65+
popd > /dev/null
66+
exit "$status"
67+
fi
68+
popd > /dev/null
69+
70+
# ADR-0081: ratchet the spec↔frontend react-block conformance against the
71+
# committed baseline. Warn-only here — run check:react-conformance --strict to
72+
# gate intentionally.
73+
if [[ -f "${FRAMEWORK_ROOT}/packages/spec/react-conformance.baseline.json" ]]; then
74+
echo "→ Ratcheting spec↔frontend react-block conformance (ADR-0081)..."
75+
( cd "${FRAMEWORK_ROOT}" && MANIFEST="${TARGET}/sdui.manifest.json" \
76+
pnpm --filter @objectstack/spec check:react-conformance \
77+
--baseline react-conformance.baseline.json ) || \
78+
echo "⚠ conformance ratchet reported new divergence — run check:react-conformance --strict to gate."
79+
fi

0 commit comments

Comments
 (0)