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:
parent
366362d62b
commit
fc524cd2d4
15 changed files with 460 additions and 34 deletions
|
|
@ -14,6 +14,7 @@
|
|||
// (once the group has a build), so `testers` asks first; `--remove` takes testers out of the managed groups.
|
||||
// `distribute --submit-review` sends the build to Beta App Review (external groups) after a confirmation; neither
|
||||
// testers nor external distribution nor the review submission are MCP tools. Pure planning: cli/lib/testflight.ts.
|
||||
import { elapsed, heartbeat, type HeartbeatOptions } from '../lib/progress';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import type { Ctx } from '../lib/ctx';
|
||||
import { confirm, need } from '../lib/ctx';
|
||||
|
|
@ -51,10 +52,12 @@ export interface BuildWait { outcome: WaitOutcome; timedOut: boolean; seen: Buil
|
|||
* Polls build `number` until processing ends (VALID, or FAILED / INVALID) or `timeoutMs` passes; logs each state change.
|
||||
* `once` reads the state a single time. Shared by `testflight wait` and `apple upload` (which waits after the upload).
|
||||
*/
|
||||
export async function waitForBuild(c: Asc, appId: string, number: string, o: { marketing?: string; timeoutMs: number; once?: boolean; tag?: string }): Promise<BuildWait> {
|
||||
export async function waitForBuild(c: Asc, appId: string, number: string, o: { marketing?: string; timeoutMs: number; once?: boolean; tag?: string } & HeartbeatOptions): Promise<BuildWait> {
|
||||
const started = Date.now();
|
||||
let delay: number | null = null, last = '';
|
||||
for (;;) {
|
||||
// polls are up to 2 minutes apart: a heartbeat in between says the wait is alive
|
||||
const beat = o.once ? null : heartbeat(ms => log(o.tag ?? TAG, `still waiting for build ${number}: ${last || 'first check'}, ${elapsed(ms)} of ${elapsed(o.timeoutMs)}`), o);
|
||||
try { for (;;) {
|
||||
const seen = await seeBuild(c, appId, number, o.marketing);
|
||||
const outcome = waitOutcome(seen);
|
||||
const line = outcome === 'missing' ? 'not listed yet (App Store Connect lists it once processing starts)' : `${seen.processingState}${seen.internal ? `, internal ${seen.internal}` : ''}`;
|
||||
|
|
@ -65,7 +68,7 @@ export async function waitForBuild(c: Asc, appId: string, number: string, o: { m
|
|||
delay = waitDelay(delay);
|
||||
if (Date.now() + delay - started > o.timeoutMs) return result(true);
|
||||
await Bun.sleep(delay);
|
||||
}
|
||||
} } finally { beat?.stop(); }
|
||||
}
|
||||
|
||||
/** The closing line for a finished wait (VALID with the next step, or FAILED / INVALID with what to do). */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue