apple.macos listing / review notes per platform + iOS-only claim warnings; apple upload of a .pkg: bounded pkgutil, macOS processing wait, heartbeats; release 409 pattern
This commit is contained in:
parent
53d57544bf
commit
1e47c2ee60
18 changed files with 417 additions and 63 deletions
|
|
@ -37,8 +37,8 @@ const TAG = 'testflight';
|
|||
const USAGE = 'usage: storebound apple testflight status | groups [sync] | testers | what-to-test --build N | info | distribute --build N --group <names> | wait --build N | expire --keep N | --older-than D';
|
||||
|
||||
/** The state of build `number` (of `marketing` version) right now; found: false while App Store Connect does not list it. */
|
||||
async function seeBuild(c: Asc, appId: string, number: string, marketing?: string): Promise<BuildSeen & { version?: string }> {
|
||||
const q = new URLSearchParams({ 'filter[app]': appId, 'filter[version]': number, 'filter[preReleaseVersion.platform]': 'IOS', include: 'preReleaseVersion,buildBetaDetail', limit: '50' });
|
||||
async function seeBuild(c: Asc, appId: string, number: string, marketing?: string, platform = 'IOS'): Promise<BuildSeen & { version?: string }> {
|
||||
const q = new URLSearchParams({ 'filter[app]': appId, 'filter[version]': number, 'filter[preReleaseVersion.platform]': platform, include: 'preReleaseVersion,buildBetaDetail', limit: '50' });
|
||||
if (marketing) q.set('filter[preReleaseVersion.version]', marketing);
|
||||
const resp = await c.asc('GET', `/v1/builds?${q}`);
|
||||
const hits = buildsWithVersion(resp).filter(b => b.attributes.version === number && (!marketing || b.marketing === marketing));
|
||||
|
|
@ -54,13 +54,13 @@ 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 } & HeartbeatOptions): Promise<BuildWait> {
|
||||
export async function waitForBuild(c: Asc, appId: string, number: string, o: { marketing?: string; platform?: 'IOS' | 'MAC_OS'; timeoutMs: number; once?: boolean; tag?: string } & HeartbeatOptions): Promise<BuildWait> {
|
||||
const started = Date.now();
|
||||
let delay: number | null = null, last = '';
|
||||
// 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 seen = await seeBuild(c, appId, number, o.marketing, o.platform);
|
||||
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}` : ''}`;
|
||||
if (line !== last) { log(o.tag ?? TAG, `build ${number}${seen.version ? ` (${seen.version})` : ''}: ${line} [${Math.round((Date.now() - started) / 60_000)} min]`); last = line; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue