Pad/scripts/release.sh
Greg Pomerantz f31f849665 Make the release process script-driven and documented
The release flow, install policy, and on-device rules previously lived in
session context. Now:

- scripts/release.sh: the executable release — gate 1 static checks,
  gate 2 full go test (incl. TestNoFramesWhileIdle), gate 3 frame-regression
  profile on the emulator, build (SKIP_CHECK=1 avoids double static checks),
  then install to EVERY connected device (emulators and phones; the
  wireless-debugging serial changes per reconnect, the loop sidesteps it).
  Any gate failure aborts before install; dirty tree is warned, not fatal.
- doc/release.md: the process, the install-to-all-devices default, the rule
  that a phone is INSTALL-ONLY during a release (on-device
  profiling/testing is diagnostic and needs explicit approval per run),
  failure-handling table, versioning gap (still gogio default 1.0.0.1), and
  emulator requirements.
- doc/README.md: release.md added to the doc table.
- architecture.md §11: pointer to the release flow.

Validated end-to-end: release.sh ran all three gates (PASS), built the APK,
and installed it on both the phone and the emulator in one command.
2026-08-20 14:54:48 -04:00

63 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Pad release: run the release gates, build the phone APK, and install it to
# every connected device.
#
# The full process, policies, and failure handling are documented in
# doc/release.md — this script is the executable form of that document.
#
# Gates (ALL must pass; any failure aborts before the install):
# 1. static checks: go vet + staticcheck (scripts/check.sh)
# 2. go test -count=1 ./... (includes TestNoFramesWhileIdle)
# 3. frame-regression profile on the EMULATOR (scripts/profile_emulator.sh)
#
# Install policy (doc/release.md):
# - The built APK is installed to EVERY connected device — emulators and
# phones. Pushing a release build to the developer's phone is the
# DEFAULT, expected behavior.
# - This script installs ONLY. It never profiles or tests a phone.
# On-device profiling/testing (e.g. scripts/profile_emulator.sh -s
# <phone serial>) is diagnostic and requires explicit developer approval
# per run.
#
# Usage:
# ./scripts/release.sh # gates + build + install to all devices
# ./scripts/release.sh --no-install
set -euo pipefail
REPO=$(cd "$(dirname "$0")/.." && pwd)
INSTALL=1
[ "${1:-}" = "--no-install" ] && INSTALL=0
if [ -n "$(git -C "$REPO" status --porcelain 2>/dev/null)" ]; then
echo "NOTE: working tree is dirty — the gates run on the current (possibly"
echo " uncommitted) state. Commit the release work before shipping."
fi
echo "=== gate 1/3: static checks ==="
"$REPO/scripts/check.sh"
echo "=== gate 2/3: go test (includes TestNoFramesWhileIdle) ==="
(cd "$REPO" && go test -count=1 ./...)
echo "=== gate 3/3: frame-regression profile (emulator only) ==="
"$REPO/scripts/profile_emulator.sh"
echo "=== build phone APK ==="
SKIP_CHECK=1 "$REPO/scripts/build_phone.sh" --no-install
if [ "$INSTALL" = "1" ]; then
echo "=== install to all connected devices ==="
serials=$(adb devices | awk 'NR>1 && $2=="device" {print $1}')
if [ -z "$serials" ]; then
echo "no connected devices — APK built at cmd/pad/pad-phone.apk;"
echo "install later with: adb -s <serial> install -r cmd/pad/pad-phone.apk"
else
for s in $serials; do
echo "-- installing on $s"
adb -s "$s" install -r "$REPO/cmd/pad/pad-phone.apk"
done
fi
fi
echo "=== RELEASE COMPLETE ==="