capability check: a checkout without .entitlements is a warning about this checkout only (built from another branch?), naming the current branch and the local branches / worktrees that have an .entitlements file, never a claim about the build; the newest built IPA (highest build number) is read (codesign -d --entitlements on macOS, else the Mach-O signature's entitlements blob) and compared as 'uploaded build N'; without one the output says the App Store Connect API does not expose a build's entitlements; exportedIpas moved to cli/lib/xcode.ts; pitfall 67; tests

This commit is contained in:
CRTkafa 2026-10-14 19:17:45 +08:00
parent daae3715bf
commit 2b07f56673
7 changed files with 230 additions and 27 deletions

View file

@ -150,6 +150,18 @@ export const showCmd = (argv: string[], auth: AscAuth | null): string =>
export interface IpaInfo { bundleId: string; version: string; build: string; minOs?: string; name?: string; platform?: string }
/** Bundle id, CFBundleShortVersionString and CFBundleVersion from Payload/<App>.app/Info.plist of an IPA. */
/** Every .ipa in the export folder and its per-build subfolders (<version>-<build>/), newest first. */
export function exportedIpas(dir: string): string[] {
if (!existsSync(dir)) return [];
const out: string[] = [];
for (const f of readdirSync(dir)) {
const p = join(dir, f);
if (f.endsWith('.ipa')) out.push(p);
else if (statSync(p).isDirectory()) for (const g of readdirSync(p)) if (g.endsWith('.ipa')) out.push(join(p, g));
}
return out.sort((x, y) => statSync(y).mtimeMs - statSync(x).mtimeMs);
}
export function ipaInfo(ipa: string | Buffer): IpaInfo {
const e = zipEntries(ipa).find(x => /^Payload\/[^/]+\.app\/Info\.plist$/.test(x.name));
if (!e) throw new Error('not an iOS app archive (no Payload/<App>.app/Info.plist)');