play build: find the Android SDK like Android Studio (ANDROID_HOME, ANDROID_SDK_ROOT, sdk.dir, default folder), pass it in the env, stop before Gradle when missing; doctor shows it. apple upload: size, per-part lines, 20 s heartbeat (api, altool, processing wait), per-part and per-call timeouts, --timeout exits 7 with the resume hint. Pitfall 25

This commit is contained in:
CRTkafa 2026-10-12 08:48:02 +08:00
parent 366362d62b
commit fc524cd2d4
15 changed files with 460 additions and 34 deletions

View file

@ -64,6 +64,9 @@ when the owner said so for this run). The MCP server offers only `apple_signing_
(exit 0), INVALID / FAILED (exit 1, Apple emails the ITMS reason) or `--timeout` (default 60m, exit 7). Run long
uploads in the background with a log: `storebound apple upload --yes > .storebound/upload.log 2>&1 &` (only
after the owner's yes).
The upload is never silent: the size at the start, a line per part, a heartbeat every 20 s ("still uploading,
4m30s, 312/890 MB (35%), part 4/12"), the same while altool runs and while the build is processed. Past
`--timeout` it stops with exit 7; the same command again resumes the build upload (raise `--timeout`).
6. **Next.** `storebound apple encryption --build N`, `storebound apple testflight distribute --build N --group Team
--dry` (`testflight` skill), `storebound apple listing --version x.y.z --build N` (`appstore-first-release`).
@ -80,6 +83,11 @@ when the owner said so for this run). The MCP server offers only `apple_signing_
(or `--version-code N`) and where the key comes from. Then without `--dry`. The AAB lands in
`build/android/<package>-<versionCode>.aab`; storebound reads the versionCode back from the bundle and warns when
the build file ignored the one it passed (read `-PversionCode` there, or `android.injected.version.code`).
The Android SDK is found the way Android Studio finds it: `ANDROID_HOME`, `ANDROID_SDK_ROOT`, `sdk.dir` in the
Gradle project's `local.properties`, then `~/Library/Android/sdk` (macOS) / `~/Android/Sdk` (Linux) /
`%LOCALAPPDATA%\Android\Sdk` (Windows), and handed to Gradle through `ANDROID_HOME` / `ANDROID_SDK_ROOT`;
`local.properties` is never written. None found: it stops before Gradle and lists the places checked.
`storebound doctor` shows the SDK path and where it came from.
3. **Upload.** `storebound play upload --track internal --dry` (read-only: checks the versionCode is free, shows
what is on the track now and the release notes languages). Then without `--dry` after a yes. Tracks: internal,
alpha (closed), beta (open). Production stays `storebound play release --version-code N --production draft` plus

View file

@ -250,6 +250,7 @@ Each entry: **symptom** → cause → what to do → what guards it now. The ful
- **Sources:** https://support.google.com/googleplay/android-developer/answer/10787469 (Data safety form, CSV import),
https://support.google.com/googleplay/android-developer/answer/13327111 (account deletion: delete-account link;
deleting other data is a separate question).
## Adding a lesson
Every bug found in real use gets an entry in `docs/pitfalls.md` and here, and, where possible, a check or a test
that fails without the fix (see CONTRIBUTING.md).
@ -296,3 +297,21 @@ that fails without the fix (see CONTRIBUTING.md).
`flow run` stops with "step N declined: <reason>" (status `declined`, never `ok`) and adds `--yes` to write steps
only with `--apply --yes` (`planStep` in `cli/lib/flow.ts`, `declinedReason` in `cli/flow.ts`).
`tests/flow.test.ts` (non-TTY flow with a confirming step and no `--yes` fails at that step with "declined").
## 25. Builds and uploads in a non-interactive shell: no SDK, no output
- **Symptom:** `storebound play build` stopped in Gradle with "SDK location not found. Define ANDROID_HOME or sdk.dir
in local.properties" although the SDK was in `~/Library/Android/sdk`. `storebound apple upload --no-wait --yes` ran
for over 10 minutes with no line at all while it sent the IPA.
- **Cause:** agents and scripts run non-interactive shells: `ANDROID_HOME` from `.zshrc` is not set there, and
`local.properties` (where Android Studio writes `sdk.dir`) is gitignored, so a fresh checkout has none. The upload
logged only every 10th part and had no timeout per part or per API call, so one large or stalled part was silence.
- **Do:** nothing special now. `play build` finds the SDK like Android Studio (ANDROID_HOME, ANDROID_SDK_ROOT,
`sdk.dir` in local.properties, the Android Studio default folder per OS), passes it to Gradle in the environment and
never writes local.properties; without one it stops before Gradle and lists what it checked (`storebound doctor`
shows the SDK and its source). `apple upload` prints the size, a line per part and a heartbeat every 20 s (also for
altool and the processing wait); `--timeout` stops it with exit 7, and running the same command again resumes.
Still run long uploads in the background with a log and report its lines.
- **Guard:** `resolveAndroidSdk` / `androidSdkEnv` in `cli/lib/tools.ts`, `cli/play/build.ts`, `cli/doctor.ts`;
`sendParts` in `cli/apple/upload.ts`, `cli/lib/progress.ts` (injectable heartbeat), `waitForBuild` in
`cli/apple/testflight.ts`, a 2-minute limit per App Store Connect call (`ASC_REQUEST_TIMEOUT_MS`);
`tests/tools-path.test.ts`, `tests/build-sign.test.ts`, `tests/upload-progress.test.ts`.