Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,61 @@ jobs:
bun build export/index.ts --compile --target=${{ matrix.target }} $EXTERNAL_FLAGS --outfile=supertag-export
fi

# Apple Silicon (and increasingly x64 on macOS 26+) kills any Mach-O that
# lacks a valid code signature with SIGKILL (exit 137) at exec — no
# Gatekeeper dialog, quarantine removal does nothing. Bun's --compile
# *usually* ad-hoc signs, but some Bun versions (and cross-compiled
# targets) ship UNSIGNED binaries, which is exactly how #84 escaped for a
# month. Re-sign explicitly here so we never depend on Bun's auto-signing.
# --remove-signature first clears any malformed/partial signature that
# would otherwise make `codesign --force` fail with "invalid format".
- name: Codesign macOS binaries (ad-hoc)
run: |
set -euo pipefail
for bin in supertag supertag-lite supertag-mcp supertag-export; do
codesign --remove-signature "$bin" 2>/dev/null || true
codesign --force --sign - --timestamp=none "$bin"
codesign --verify --verbose "$bin"
done

# Verification gate: actually EXECUTE every binary. This is the check that
# would have caught #84 in CI instead of a month later. An unsigned Mach-O
# is SIGKILLed by the kernel at exec (exit 137) on Apple Silicon, so we
# only need to prove each binary *starts*. supertag/-lite/-export exit
# cleanly on --version; supertag-mcp ignores the flag and runs as a stdio
# server, so we use a background guard (no GNU `timeout` on macOS runners):
# launch, wait 2s, and if it's still alive it execed fine (kill = pass);
# otherwise the only failure we care about is 137 (kernel SIGKILL).
- name: Smoke-test binaries
run: |
set -uo pipefail
RUNNER=""
if [ "${{ matrix.target }}" = "bun-darwin-arm64" ]; then
RUNNER="" # native arm64 on macos-latest
elif arch -x86_64 true 2>/dev/null; then
RUNNER="arch -x86_64" # x64 via Rosetta
else
echo "Rosetta unavailable; skipping x64 execution (signatures verified above)"
exit 0
fi
smoke() {
local bin="$1"
$RUNNER "./$bin" --version </dev/null >/dev/null 2>&1 &
local pid=$!
sleep 2
if kill -0 "$pid" 2>/dev/null; then
kill "$pid" 2>/dev/null; wait "$pid" 2>/dev/null || true
echo "ok: $bin started (long-running; killed after 2s)"
else
wait "$pid"; local rc=$?
if [ "$rc" -eq 137 ]; then
echo "FAIL: $bin was SIGKILLed (exit 137) — invalid/missing code signature"; exit 1
fi
echo "ok: $bin exited $rc"
fi
}
for b in supertag supertag-lite supertag-mcp supertag-export; do smoke "$b"; done

- name: Create distribution package
run: |
DIST_NAME="supertag-cli-${{ matrix.suffix }}"
Expand Down
Loading