Pad/doc/release.md
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

75 lines
3.6 KiB
Markdown

# Release process
A release is **`./scripts/release.sh`** — that one command is the
executable form of this document. If this document and the script ever
disagree, fix both in the same change.
## What a release does
1. **Gate 1 — static checks**: `scripts/check.sh` (go vet + staticcheck).
2. **Gate 2 — test suite**: `go test -count=1 ./...` — includes
`TestNoFramesWhileIdle` (internal/test/e2e), the headless
frame-regression guard.
3. **Gate 3 — frame-regression profile, EMULATOR only**:
`scripts/profile_emulator.sh` (auto-selects an emulator; it never
auto-selects a phone). See architecture.md §11 for what it measures and
why the budgets are shaped the way they are.
4. **Build**: `scripts/build_phone.sh --no-install` (arm64+arm APK →
`cmd/pad/pad-phone.apk`; static checks are skipped here, already gate 1).
5. **Install to every connected device** — emulators **and phones**.
Any gate failure aborts before the install. The working tree may be dirty;
the script warns, but the gates then certify the *current* (possibly
uncommitted) state — commit the release work before shipping.
## Install policy
- Pushing a release build to the developer's phone is the **default and
expected** behavior — `release.sh` installs to all `adb devices` entries,
which is what makes the phone just work without knowing its serial
(the wireless-debugging `IP:port` changes on every reconnect; the
install loop sidesteps that entirely).
- On a phone that has never had the app, grant **"All files access"**
(MANAGE_EXTERNAL_STORAGE) in system settings after the first install.
## On-device profiling/testing: NOT part of a release
The release touches a phone **only to install the APK**. It never
profiles, tests, force-stops, or otherwise drives a phone:
- On-device runs (e.g. `scripts/profile_emulator.sh -s <phone serial>`)
are **diagnostics**: they force-stop the app, seed and remove a file in
its storage, and read its profiler output. The developer may be using the
phone while a release runs.
- Therefore an on-device run requires **explicit approval in the moment**
(ask first, name the serial), and its results are informational, never a
gate. The frame-regression *gate* is tier 2 (headless) + tier 3
(emulator) only.
## Failure handling
| Gate | Fails on | First things to check |
|---|---|---|
| 1 static | vet/staticcheck findings | The findings; don't waive without a reason in the commit message |
| 2 tests | any test | `go test -count=1 -run <Name> ./...` to isolate; e2e tests are deterministic — a flake is a bug in the test |
| 3 profile | a phase over its frame budget | The printed phases + `PERF`/`PERF-PRESENT` logcat lines (a spinner is usually obvious); confirm the emulator wasn't under host load (rerun once before investigating) |
| build | gogio/apktool/sign | Toolchain notes in `scripts/build_phone.sh` header |
If the profile gate is in question, a diagnostic run **on the phone**
(requires approval) is the escalation path — not a replacement for the gate.
## Versioning (known gap)
The APK is currently built with the gogio-default version
(`1.0.0.1`); releases do **not** bump a version yet. When release
distribution starts mattering, add a version step here (and to
`release.sh`) — until then, "which release" is identified by the git
commit the APK was built from.
## Emulator requirements
Gate 3 needs a running emulator (`adb devices` shows `emulator-*`).
`scripts/emu.sh` manages the AVD (see its header); the AVD must have had
"All files access" granted once (it has). No phone needs to be connected
for a release to succeed — the install step simply reports no devices.