commit 9b2f7411de60da7bddda1376723fbcf9df2157f2
parent b00bb7a949692054e8d4258003e64db1fb66f470
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 17 Jun 2026 14:38:50 -0700
test release artifacts on macOS arm64
Diffstat:
5 files changed, 182 insertions(+), 8 deletions(-)
diff --git a/doc/RELEASE.md b/doc/RELEASE.md
@@ -74,7 +74,15 @@ emits + signs the channel index. It asserts a clean git tree and refuses the
in-tree test key. Freestanding targets have no host to run on and produce no
artifact. Knobs: `KIT_SIGN_KEY` (required), `KIT_RELEASE_URL_BASE` (mirror base
URLs), `KIT_RELEASE_TARGETS`, `KIT_VM=0` (drop FreeBSD/Windows on a VM-less
-runner), `KIT_CHANNEL`.
+runner), `KIT_CHANNEL`, `KIT_RELEASE_OUT_DIR` (artifact output directory,
+default `build/release-dist`). Hermetic tests that intentionally sign with the
+in-tree non-release key must also set `KIT_RELEASE_ALLOW_TEST_KEY=1`.
+
+Targeted validation for the runnable arm64 macOS artifact is
+`make test-release-macos-aa64`: it drives `scripts/release.sh` for `macos-aa64`
+with the in-tree non-release key, installs the `.kpkg` under an isolated
+`KIT_HOME`, unpacks the `.tar.gz` under a separate isolated `KIT_HOME`, and runs
+both resulting `kit` binaries.
Detached signatures over arbitrary files (the `.tar.gz.minisig` and the index
signature) are produced by `kit pkg sign -s KEY [-o OUT] FILE`, which writes a
diff --git a/driver/cmd/update.c b/driver/cmd/update.c
@@ -90,7 +90,7 @@ static int up_version_installed(const UpPaths* p, const char* ver) {
/* Snapshot installed version names into vers[] (ascending CalVer). Returns the
* count. Non-CalVer entries keep insertion order relative to each other. */
static int up_list_installed(DriverEnv* env, const UpPaths* p,
- char vers[][KIT_PKG_VERSION_MAX], int cap) {
+ char (*vers)[KIT_PKG_VERSION_MAX], int cap) {
DriverDirHandle* d = driver_open_dir(env, p->versions);
int n = 0, a;
uint64_t idx = 0;
diff --git a/mk/test.mk b/mk/test.mk
@@ -76,6 +76,7 @@ TEST_TARGETS = \
test-driver-pkg \
test-dist \
test-selfdist \
+ test-release-macos-aa64 \
test-driver-strings \
test-driver-tools \
test-driver-wasm \
@@ -335,6 +336,14 @@ test-driver-pkg: bin
test-selfdist: bin
@KIT=$(abspath $(BIN)) sh test/dist/run.sh
+# test-release-macos-aa64: full release-artifact smoke for the runnable arm64
+# macOS target. Drives scripts/release.sh with the non-release test key into an
+# isolated output dir, then proves both the .kpkg update path and the .tar.gz
+# bootstrap-unpack path produce runnable kit binaries under separate KIT_HOME
+# roots. Opt-in because it performs a release cross-build.
+test-release-macos-aa64: bin
+ @KIT=$(abspath $(BIN)) sh test/release/run.sh
+
# test-extlink: prove kit-emitted objects link with the *system* linkers
# (LLVM lld ELF/COFF/Mach-O personalities + Apple ld), not just kit's own
# `ld`. Lanes self-skip when a linker / SDK is absent, so it is safe in the
diff --git a/scripts/release.sh b/scripts/release.sh
@@ -37,6 +37,9 @@
# Environment knobs
# -----------------
# KIT_SIGN_KEY (required) path to the real release minisign secret key.
+# KIT_RELEASE_ALLOW_TEST_KEY
+# (optional, default 0) set to 1 only for hermetic tests
+# that intentionally sign with the in-tree non-release key.
# KIT_RELEASE_URL_BASE (optional) one or more space-separated mirror base URLs
# for the channel index `url` lines. Each artifact's URL
# is "<base>/<filename>". Defaults to a GitHub-Releases-
@@ -50,6 +53,8 @@
# as in scripts/hosted.sh.
# KIT_CHANNEL (optional, default "stable") channel name for the index
# and the index file basename (<channel>.index).
+# KIT_RELEASE_OUT_DIR (optional, default build/release-dist) output directory
+# for artifacts, staging trees, and the channel index.
# KIT (optional) path to a prebuilt native kit to use as the
# packaging tool (default: the build/release/kit produced
# by `make RELEASE=1 bin`).
@@ -62,6 +67,12 @@ HOSTED="$ROOT/scripts/hosted.sh"
die() { printf 'release: %s\n' "$*" >&2; exit 1; }
log() { printf 'release: %s\n' "$*" >&2; }
+canon_path() {
+ local dir base
+ dir="$(dirname "$1")"
+ base="$(basename "$1")"
+ (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$base")
+}
# ---- preconditions ---------------------------------------------------------
# A real signing key is mandatory; releasing with the test key is never valid.
@@ -69,6 +80,11 @@ log() { printf 'release: %s\n' "$*" >&2; }
"KIT_SIGN_KEY is unset — set it to the real release minisign secret key.
(Unlike 'make dist', release.sh does NOT fall back to the in-tree test key.)"
[ -f "$KIT_SIGN_KEY" ] || die "KIT_SIGN_KEY=$KIT_SIGN_KEY is not a file"
+TEST_SIGN_KEY="$ROOT/test/dist/keys/nonrelease.key"
+if [ "${KIT_RELEASE_ALLOW_TEST_KEY:-0}" != 1 ] &&
+ [ "$(canon_path "$KIT_SIGN_KEY")" = "$(canon_path "$TEST_SIGN_KEY")" ]; then
+ die "KIT_SIGN_KEY points at the in-tree NON-RELEASE test key; set KIT_SIGN_KEY to the real release key"
+fi
[ -f "$ROOT/VERSION" ] || die "no VERSION file at repo root"
VERSION="$(tr -d ' \t\r\n' < "$ROOT/VERSION")"
@@ -90,7 +106,7 @@ CHANNEL="${KIT_CHANNEL:-stable}"
DEFAULT_URL_BASE="https://github.com/kit/kit/releases/download/v$VERSION"
URL_BASES="${KIT_RELEASE_URL_BASE:-$DEFAULT_URL_BASE}"
-OUT_DIR="$ROOT/build/release-dist"
+OUT_DIR="${KIT_RELEASE_OUT_DIR:-$ROOT/build/release-dist}"
INDEX_FILE="$OUT_DIR/$CHANNEL.index"
# ---- the native packaging tool ---------------------------------------------
@@ -200,15 +216,36 @@ build_target() {
# Each target gets an isolated RT_BUILD_DIR so per-arch objects never mix.
log "building rt variant $rt_variant"
local rt_build_dir="$ROOT/build/release-rt/$token"
+ local rt_tool_dir="$OUT_DIR/toolchain/$token"
rm -rf "$rt_build_dir"
- local rt_cc="$KIT cc -target $triple"
- [ -n "$sysroot" ] && rt_cc="$rt_cc --sysroot $sysroot"
+ rm -rf "$rt_tool_dir"
+ mkdir -p "$rt_tool_dir"
+ if [ -n "$sysroot" ]; then
+ cat > "$rt_tool_dir/cc" <<EOF
+#!/bin/sh
+exec "$KIT" cc -target "$triple" --sysroot "$sysroot" "\$@"
+EOF
+ else
+ cat > "$rt_tool_dir/cc" <<EOF
+#!/bin/sh
+exec "$KIT" cc -target "$triple" "\$@"
+EOF
+ fi
+ cat > "$rt_tool_dir/ar" <<EOF
+#!/bin/sh
+exec "$KIT" ar "\$@"
+EOF
+ cat > "$rt_tool_dir/as" <<EOF
+#!/bin/sh
+exec "$KIT" as "\$@"
+EOF
+ chmod +x "$rt_tool_dir/cc" "$rt_tool_dir/ar" "$rt_tool_dir/as"
make "rt-$rt_variant" \
BIN="$KIT" \
RT_BUILD_DIR="$rt_build_dir" \
- RT_CC="$rt_cc" \
- RT_AR="$KIT ar" \
- RT_AS="$KIT as"
+ RT_CC="$rt_tool_dir/cc" \
+ RT_AR="$rt_tool_dir/ar" \
+ RT_AS="$rt_tool_dir/as"
local rt_archive="$rt_build_dir/$rt_variant/libkit_rt.a"
[ -f "$rt_archive" ] || die "$token: rt archive missing at $rt_archive"
diff --git a/test/release/run.sh b/test/release/run.sh
@@ -0,0 +1,120 @@
+#!/bin/sh
+# Full release artifact smoke for the runnable arm64 macOS target.
+#
+# This deliberately drives scripts/release.sh rather than reimplementing the
+# staging/package steps. It uses the in-tree non-release key and a private output
+# directory, then validates both shipped formats:
+# - .kpkg installs through kit update under an isolated KIT_HOME
+# - .tar.gz unpacks through kit pkg unpack under a separate isolated KIT_HOME
+#
+# Run by: make test-release-macos-aa64
+
+set -u
+
+script_dir=$(cd "$(dirname "$0")" && pwd)
+repo_root=$(cd "$script_dir/../.." && pwd)
+
+KIT="${KIT:-$repo_root/build/kit}"
+if [ ! -x "$KIT" ]; then
+ echo "release: kit binary not found at $KIT" >&2
+ exit 2
+fi
+
+work=$(mktemp -d "${TMPDIR:-/tmp}/kit-release-test.XXXXXX")
+trap 'rm -rf "$work"' EXIT
+
+HOME="$work/home"
+SOURCE_DATE_EPOCH=1
+export HOME SOURCE_DATE_EPOCH
+mkdir -p "$HOME"
+
+KIT_KIT_DIR="$repo_root/test/lib"
+. "$repo_root/test/lib/kit_sh_kit.sh"
+kit_report_init
+
+SECKEY="$repo_root/test/dist/keys/nonrelease.key"
+PUBKEY="$repo_root/test/dist/keys/nonrelease.pub"
+OUT_DIR="$work/release-dist"
+VERSION=$(tr -d ' \t\r\n' < "$repo_root/VERSION")
+TARGET=macos-aa64
+TRIPLE=aarch64-apple-darwin
+HOST_TRIPLE=aarch64-macos
+BASE="$OUT_DIR/kit-$VERSION-$TRIPLE"
+
+host_os=$(uname -s 2>/dev/null || echo unknown)
+host_arch=$(uname -m 2>/dev/null || echo unknown)
+case "$host_os:$host_arch" in
+ Darwin:arm64|Darwin:aarch64) ;;
+ *)
+ skip_test "release-macos-aa64-host" \
+ "requires arm64 macOS host, got $host_os/$host_arch"
+ kit_summary release-macos-aa64
+ kit_exit
+ ;;
+esac
+
+if ! command -v xcrun >/dev/null 2>&1; then
+ skip_test "release-macos-aa64-xcrun" "xcrun not available"
+ kit_summary release-macos-aa64
+ kit_exit
+fi
+
+runs_version() {
+ name=$1
+ exe=$2
+ home=$3
+ if KIT_HOME="$home" "$exe" --version > "$work/$name.out" 2> "$work/$name.err" &&
+ grep -F "kit $VERSION " "$work/$name.out" >/dev/null 2>&1 &&
+ grep -F "$HOST_TRIPLE" "$work/$name.out" >/dev/null 2>&1; then
+ ok "$name"
+ else
+ { cat "$work/$name.err"; cat "$work/$name.out"; } > "$work/$name.diag"
+ not_ok "$name" "$work/$name.diag"
+ fi
+}
+
+if env KIT= \
+ KIT_SIGN_KEY="$SECKEY" \
+ KIT_RELEASE_ALLOW_TEST_KEY=1 \
+ KIT_RELEASE_ALLOW_DIRTY=1 \
+ KIT_RELEASE_TARGETS="$TARGET" \
+ KIT_RELEASE_OUT_DIR="$OUT_DIR" \
+ KIT_VM=0 \
+ "$repo_root/scripts/release.sh" \
+ > "$work/release-build-$TARGET.out" \
+ 2> "$work/release-build-$TARGET.err"; then
+ ok "release-build-$TARGET"
+else
+ not_ok "release-build-$TARGET" "$work/release-build-$TARGET.err"
+ kit_summary release-macos-aa64
+ kit_exit
+fi
+
+assert_file_exists "release-kpkg-exists" "$BASE.kpkg"
+assert_file_exists "release-targz-exists" "$BASE.tar.gz"
+assert_file_exists "release-targz-minisig-exists" "$BASE.tar.gz.minisig"
+assert_file_exists "release-index-exists" "$OUT_DIR/stable.index"
+assert_file_exists "release-index-minisig-exists" "$OUT_DIR/stable.index.minisig"
+
+KP_HOME="$work/kit-home-kpkg"
+run_ok "kpkg-update-installs" env KIT_HOME="$KP_HOME" \
+ "$KIT" update --key "$PUBKEY" "$BASE.kpkg"
+contains "kpkg-update-message" "$work/kpkg-update-installs.out" \
+ "installed kit $VERSION (now current)"
+assert_file_exists "kpkg-current-bin-exists" "$KP_HOME/versions/$VERSION/bin/kit"
+is_executable "kpkg-current-bin-exec" "$KP_HOME/bin/kit"
+runs_version "kpkg-installed-kit-runs" "$KP_HOME/bin/kit" "$KP_HOME"
+
+TG_HOME="$work/kit-home-targz"
+TG_ROOT="$work/targz-root"
+mkdir -p "$TG_ROOT"
+run_ok "targz-unpacks" env KIT_HOME="$TG_HOME" \
+ "$KIT" pkg unpack --verify -p "$PUBKEY" "$BASE.tar.gz" -C "$TG_ROOT"
+contains "targz-unpack-message" "$work/targz-unpacks.out" \
+ "unpacked kit $VERSION to $TG_ROOT"
+assert_file_exists "targz-bin-exists" "$TG_ROOT/bin/kit"
+is_executable "targz-bin-exec" "$TG_ROOT/bin/kit"
+runs_version "targz-kit-runs" "$TG_ROOT/bin/kit" "$TG_HOME"
+
+kit_summary release-macos-aa64
+kit_exit