CI / verify (pull_request) Successful in 1m4s
CI / infrastructure-smoke (pull_request) Successful in 37s
CI / migration-smoke (pull_request) Successful in 1m54s
CI / package-release (pull_request) Successful in 32s
CI / image-build (pull_request) Successful in 30s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m32s
The package-release job failed its clean-tree assertion in CI. Reproduced as root in a container with a bind-mounted checkout, as the Gitea runner does: after checkout the tree is clean; `pnpm install --frozen-lockfile` then creates `.pnpm-store/` (17,272 untracked files) at the checkout's root, because pnpm keeps its store on the node_modules file system and the checkout is its own mount; `pnpm build` changes nothing. No tracked file is ever modified. - `.pnpm-store/` is ignored, like node_modules: a package cache, never source. The clean-commit requirement is unchanged for every tracked file and every untracked file Git does not ignore. - The clean-tree failure now lists `git status --short` and `git diff --stat`. - Nothing is built before the clean-source assertion: the gate no longer runs a global `pnpm build` first. The builder asserts a clean tree, builds, then fails if its build changed the tree, before packing. Core's verifier is built after both releases, for the consumer proof only. - Every secondary offline install (the second worktree, the consumer module) uses the workspace install's own store explicitly, since pnpm picks a store per file system and those directories are on another. Co-Authored-By: Claude Opus 5.5 <[email protected]>
73 lines
3.4 KiB
Bash
Executable File
73 lines
3.4 KiB
Bash
Executable File
#!/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."
|