Ship-step contract for pipelines: uniform exit codes (0/1/2/3/4/7) in cli/lib/ship-step.ts, one final --json line, --result-file (atomic, also on failure), --progress json, --env-file with secret redaction, --version-from; idempotent play upload / apple upload / play release / apple submit re-runs end with exit 7; play upload takes --track production and --version-code
This commit is contained in:
parent
4eac8e8cd8
commit
06a0b424f5
14 changed files with 928 additions and 24 deletions
|
|
@ -17,6 +17,8 @@ import { playTargetSdkProblem, targetSdkFile } from '../lib/store-minimums';
|
|||
import { playClient } from './client';
|
||||
import { usedVersionCodes } from './next-version-code';
|
||||
import { readPlayCopy, refusePlayNotes } from './listing';
|
||||
import { shipNoop, shipPhase, shipReport } from '../lib/ship-step';
|
||||
import { consoleUrl, playTrackPage } from '../lib/console-links';
|
||||
|
||||
const TRACKS = ['internal', 'alpha', 'beta', 'production'];
|
||||
|
||||
|
|
@ -56,8 +58,10 @@ export async function run(ctx: Ctx): Promise<void> {
|
|||
const sdkWhy = playTargetSdkProblem(aabInfo(aab).targetSdk, { where: targetSdkFile(root) });
|
||||
if (sdkWhy) throw new Error(`${aab}: not released, ${sdkWhy}`);
|
||||
}
|
||||
shipReport({ track: tracks.map(t => t.track).join(','), url: consoleUrl(playTrackPage(tracks.length === 1 ? tracks[0]!.track : undefined)) });
|
||||
const play = await playClient(root, pkg);
|
||||
let released = fixed ?? '';
|
||||
let nothing = false;
|
||||
try {
|
||||
await play.edit(async (id, ctl) => {
|
||||
let code = fixed ?? '';
|
||||
|
|
@ -69,11 +73,13 @@ export async function run(ctx: Ctx): Promise<void> {
|
|||
code = String(info.versionCode);
|
||||
log('play', `versionCode ${code} is on Play already: not uploaded again`);
|
||||
} else {
|
||||
shipPhase('upload', `uploading ${aab}`, 0);
|
||||
log('play', `uploading ${aab} (${(statSync(aab).size / 1048576).toFixed(1)} MB), this can take minutes`);
|
||||
const b = await play.call<{ versionCode: number }>('POST', `${play.UPLOAD}/edits/${id}/bundles?uploadType=media`,
|
||||
new Uint8Array(readFileSync(aab)), { 'Content-Type': 'application/octet-stream' });
|
||||
code = String(b.versionCode);
|
||||
uploaded = true;
|
||||
shipPhase('upload', `uploaded versionCode ${code}`, 100);
|
||||
log('play', `uploaded versionCode ${code}`);
|
||||
}
|
||||
}
|
||||
|
|
@ -90,7 +96,8 @@ export async function run(ctx: Ctx): Promise<void> {
|
|||
changed++;
|
||||
log('play', `${t.track} <- ${code} (${t.status}, notes in ${notes.length} languages)`);
|
||||
}
|
||||
if (!changed && !uploaded) ctl.unchanged();
|
||||
if (!changed && !uploaded) { nothing = true; ctl.unchanged(); }
|
||||
else shipPhase('commit', `${changed} track(s) changed`);
|
||||
}, { dry: a.has('dry'), retries: aab ? 0 : 3, notSentForReview: a.has('not-sent-for-review'),
|
||||
// the staged rollout share is part of the plan (it was applied but not shown in the dry run)
|
||||
summary: `release ${a.get('name') ?? (aab ?? `versionCode ${fixed}`)}: ${tracks.map(t => `${t.track} ${t.status}${t.status === 'inProgress' ? ` ${Math.round(Number(fraction ?? 0.1) * 100)}%` : ''}`).join(', ')}` });
|
||||
|
|
@ -99,6 +106,8 @@ export async function run(ctx: Ctx): Promise<void> {
|
|||
throw new Error(`${(e as Error).message}\n\nThis app has never been published: the API may only create DRAFT releases. Re-run with --production draft, then send it from the Console (skill play-first-release).`);
|
||||
throw e;
|
||||
}
|
||||
// the ship-step contract: every track holds this release already (and no upload): nothing to do, exit 7
|
||||
if (nothing && !a.has('dry')) shipNoop({ build: released || undefined, state: tracks.map(t => t.status).join(',') });
|
||||
const prod = tracks.find(t => t.track === 'production');
|
||||
if (prod) {
|
||||
// Play's default: an approved release goes live by itself (managed publishing is a console-only setting)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue