#!/usr/bin/env bash # The package release gate (ADR 0053): what must pass before a future step may publish a package # train. It publishes nothing. # # bash scripts/test-package-release.sh [--allow-modified] # # 1. Builds the public package train from this checkout (`scripts/package-release.ts`): clean build # output, pack, inspect, release manifest. # 2. Builds it again from a separate worktree of the same commit, at another absolute path, and # requires the two release directories to be byte-identical: every tarball, SHA256SUMS, and the # manifest. # 3. Builds Core's verifier, then installs the release into the standalone fixture and proves it # builds, packages, and verifies (`scripts/test-standalone-module.sh`). # # Nothing is built before step 1: the release builder asserts a clean source tree first, builds, and # asserts the build changed none of it. Every offline install uses the workspace install's own store. # # `--allow-modified` is for local development on a modified source tree. The second build is then # made in this checkout again, because a worktree of the commit would not hold the modifications. set -euo pipefail repository_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" allow_modified=() if [[ "${1:-}" == "--allow-modified" ]]; then allow_modified=(--allow-modified) elif (($#)); then echo "usage: test-package-release.sh [--allow-modified]" >&2 exit 64 fi # The workspace install's own pnpm store. pnpm chooses a store per file system, so an install in a # temporary directory would otherwise look in another, empty one; every install here is offline. store="$(dirname "$(cd "$repository_root" && pnpm store path)")" export EKKLESIA_PNPM_STORE="$store" work="$(mktemp -d "${TMPDIR:-/tmp}/ekklesia-package-release-XXXXXX")" worktree="$work/second-checkout" cleanup() { if [[ -d "$worktree" ]]; then git -C "$repository_root" worktree remove --force "$worktree" >/dev/null 2>&1 || true fi rm -rf "$work" } trap cleanup EXIT echo "==> Building the package train" node "$repository_root/scripts/package-release.ts" --out "$work/first" "${allow_modified[@]}" release="$(find "$work/first" -mindepth 1 -maxdepth 1 -type d)" echo "==> Building it again, to prove the artifacts are reproducible" if ((${#allow_modified[@]})); then node "$repository_root/scripts/package-release.ts" --out "$work/second" "${allow_modified[@]}" >/dev/null else git -C "$repository_root" worktree add --detach --quiet "$worktree" HEAD (cd "$worktree" && pnpm install --offline --frozen-lockfile --store-dir "$store" --reporter=silent) node "$worktree/scripts/package-release.ts" --out "$work/second" >/dev/null fi if ! diff -r "$release" "$(find "$work/second" -mindepth 1 -maxdepth 1 -type d)"; then echo "package release gate failed: two builds of the same commit produced different artifacts" >&2 exit 1 fi echo " byte-identical: $(ls "$release" | wc -l) files" # The consumer proof verifies with Core's own verifier. Built only now, after both releases: the # release builder asserts a clean source tree before it builds anything. echo "==> Building Core's verifier" (cd "$repository_root" && pnpm exec turbo run build --filter=@ekklesia/core --output-logs=errors-only >/dev/null) echo "==> Consuming the release from a standalone module" bash "$repository_root/scripts/test-standalone-module.sh" --release "$release" "${allow_modified[@]}" echo "Package release gate passed."