apple upload: find the IPA of a build made with --out (build notes it in .storebound/last-apple-build.json; upload --out; the error names every folder searched and the last build's IPA)

This commit is contained in:
CRTkafa 2026-10-27 18:58:48 +07:00
parent ef80cd2760
commit 9a878d6562
6 changed files with 58 additions and 11 deletions

View file

@ -1,7 +1,7 @@
// Xcode builds without Xcode's UI: find the workspace / project and scheme (native, Capacitor, React Native, Flutter,
// Unity-exported projects), build the xcodebuild archive and export command lines, read an IPA's Info.plist.
// Pure except scanXcode (a bounded directory walk) and ipaInfo (reads the IPA).
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
import { basename, dirname, join, relative } from 'node:path';
import { parsePlist, type PlistValue } from './plist';
import { zipEntries, zipRead } from './zip';
@ -266,3 +266,21 @@ export function remoteBuildSession(env: Record<string, string | undefined>, mana
if (managerName && managerName !== 'Aqua') return `this is not the logged-in GUI session (launchctl manager: ${managerName})`;
return null;
}
/** Where `apple build` notes its last IPA for `apple upload`: .storebound/last-apple-build.json (gitignored). */
export const lastBuildFile = (root: string): string => join(root, '.storebound', 'last-apple-build.json');
export function recordLastBuild(root: string, r: { ipa: string; out: string; version: string; build: string }): void {
try { mkdirSync(join(root, '.storebound'), { recursive: true }); writeFileSync(lastBuildFile(root), `${JSON.stringify(r, null, 2)}\n`); } catch { /* best effort */ }
}
export function readLastBuild(root: string): { ipa: string; out: string; version?: string; build?: string } | null {
try { const j = JSON.parse(readFileSync(lastBuildFile(root), 'utf8')); return typeof j?.ipa === 'string' && typeof j?.out === 'string' ? j : null; } catch { return null; }
}
/** The export folders `apple upload` searches, in order: --out, else the last build's out (a --out that build used),
* then apple.build.out / build/ios. Duplicates dropped. */
export function uploadSearchDirs(o: { flagOut?: string; lastOut?: string; configOut: string }): string[] {
const dirs = o.flagOut ? [o.flagOut] : [...(o.lastOut ? [o.lastOut] : []), o.configOut];
return [...new Set(dirs.map(d => join(d, 'export')))];
}