Skip to content

Commit 383c247

Browse files
xuyushun441-sysos-zhuangclaude
authored
ci(release): pre-publish backward-compat smoke against live hotcrm (#2035) (#2093)
The last layer of the third-party validation strategy from #2035: a live ceiling above the deterministic in-repo floor (@objectstack/downstream-contract, #2089). `scripts/downstream-smoke.sh` clones objectstack-ai/hotcrm at a pinned tag (v1.2.0), installs it against the PUBLISHED @objectstack/* packages, overlays the freshly-built — unreleased — @objectstack/spec dist, and runs hotcrm's own `typecheck` + `objectstack validate`. If the about-to-publish spec breaks a real, independently-authored third-party consumer, the release is blocked. Wired into release.yml between the build and the changesets publish step, so it runs only in the release pipeline (never reddens a feature PR). Mirrors the existing console-SPA step that already clones an external repo at a pinned ref. Verified end-to-end locally: clone hotcrm@v1.2.0 → install → overlay current spec → typecheck + validate both pass (15 objects / 15 pages / 10 reports / 11 actions / 17 flows). Override the pinned ref with HOTCRM_REF. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 8545176 commit 383c247

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ jobs:
5858
# prepublishOnly guard in @objectstack/console passes.
5959
run: bash scripts/build-console.sh
6060

61+
- name: Downstream backward-compat smoke (live hotcrm)
62+
# Pre-publish gate (#2035): the about-to-publish @objectstack/spec must
63+
# not break a real third-party consumer pinned to a published release.
64+
# Clones objectstack-ai/hotcrm@${HOTCRM_REF}, installs it (published
65+
# deps), overlays the freshly-built spec dist, and runs hotcrm's own
66+
# typecheck + `objectstack validate`. A red here blocks the publish.
67+
# The deterministic in-repo floor is @objectstack/downstream-contract;
68+
# this is the live ceiling.
69+
env:
70+
HOTCRM_REF: v1.2.0
71+
run: bash scripts/downstream-smoke.sh
72+
6173
- name: Create Release Pull Request or Publish to npm
6274
id: changesets
6375
uses: changesets/action@v1

scripts/downstream-smoke.sh

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env bash
2+
# downstream-smoke.sh — pre-publish backward-compatibility gate (#2035).
3+
#
4+
# The spec package IS the third-party API. In-repo consumers (examples,
5+
# @objectstack/dogfood, downstream-contract) co-evolve with the spec, so they
6+
# cannot prove the *about-to-publish* spec still works for a real, independently
7+
# authored consumer pinned to a PUBLISHED release.
8+
#
9+
# This clones objectstack-ai/hotcrm at a pinned tag, installs it (pulling the
10+
# published @objectstack/* packages), overlays the freshly-built — i.e.
11+
# unreleased — @objectstack/spec dist, and runs hotcrm's own typecheck +
12+
# `objectstack validate`. A failure means the release would break a real third
13+
# party: block the publish.
14+
#
15+
# Requires `pnpm run build` (or at least the spec build) to have run first.
16+
# Override the pinned ref with HOTCRM_REF.
17+
set -euo pipefail
18+
19+
HOTCRM_REF="${HOTCRM_REF:-v1.2.0}"
20+
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
21+
SPEC_DIST="$REPO_ROOT/packages/spec/dist"
22+
23+
if [ ! -d "$SPEC_DIST" ]; then
24+
echo "::error::spec dist not found at $SPEC_DIST — build it first (pnpm --filter @objectstack/spec build)."
25+
exit 1
26+
fi
27+
28+
WORK="$(mktemp -d)"
29+
cleanup() { rm -rf "$WORK"; }
30+
trap cleanup EXIT
31+
32+
echo "→ Cloning objectstack-ai/hotcrm@${HOTCRM_REF} ..."
33+
git clone --quiet --depth 1 --branch "$HOTCRM_REF" https://github.com/objectstack-ai/hotcrm.git "$WORK/hotcrm"
34+
cd "$WORK/hotcrm"
35+
36+
echo "→ Installing hotcrm (published @objectstack/* deps) ..."
37+
pnpm install --frozen-lockfile 2>/dev/null || pnpm install --no-frozen-lockfile
38+
39+
DEST="node_modules/@objectstack/spec/dist"
40+
if [ ! -d "$DEST" ]; then
41+
echo "::error::hotcrm did not install @objectstack/spec — cannot run the gate."
42+
exit 1
43+
fi
44+
45+
echo "→ Overlaying the unreleased @objectstack/spec dist into hotcrm ..."
46+
rm -rf "$DEST"
47+
cp -R "$SPEC_DIST" "$DEST"
48+
49+
echo "→ hotcrm typecheck (against unreleased spec) ..."
50+
pnpm run typecheck
51+
52+
echo "→ hotcrm validate (loader parses all metadata against unreleased spec) ..."
53+
pnpm run validate
54+
55+
echo "✅ Downstream smoke passed — unreleased @objectstack/spec is backward compatible with hotcrm@${HOTCRM_REF}."

0 commit comments

Comments
 (0)