kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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:
Mdoc/RELEASE.md | 10+++++++++-
Mdriver/cmd/update.c | 2+-
Mmk/test.mk | 9+++++++++
Mscripts/release.sh | 49+++++++++++++++++++++++++++++++++++++++++++------
Atest/release/run.sh | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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