diff --git a/CHANGELOG.md b/CHANGELOG.md index 3362120..e3ef69b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## Unreleased +- **iPhone Duo:** the live API names the platform IPHONE_APP_STORE (not IOS); accepted. A Duo problem now warns and the other screenshot sets still upload. + ## 0.8.72 ยท 2026-11-08 - **iPhone Duo screenshots upload.** `apple screenshots` now sends them through the App Asset Library (display class diff --git a/cli/apple/duo-library.ts b/cli/apple/duo-library.ts index 86c620e..8e090fc 100644 --- a/cli/apple/duo-library.ts +++ b/cli/apple/duo-library.ts @@ -22,11 +22,11 @@ export const DUO_CATEGORY = 'APP_SCREENSHOTS_AND_PREVIEWS'; export const DUO_MAX = 10; const sumOf = (a: J | undefined): string | undefined => /^storebound ([0-9a-f]{32})$/.exec(String(a?.attributes?.referenceName ?? ''))?.[1]; -/** iOS placement profile group ids of the IPHONE_DUO display class in an appAssetLibraryRefData response. Pure. */ +/** iPhone placement profile group ids (platform IOS or IPHONE_APP_STORE, as the live API answers) of the IPHONE_DUO display class in an appAssetLibraryRefData response. Pure. */ export function duoGroups(refData: J[]): string[] { const ids = new Set(); for (const r of refData) for (const g of (r?.attributes?.placementProfileGroups ?? []) as J[]) - if (g?.displayClassId === 'IPHONE_DUO' && (!g.platform || g.platform === 'IOS') && g.placementProfileGroupId) ids.add(String(g.placementProfileGroupId)); + if (g?.displayClassId === 'IPHONE_DUO' && (!g.platform || /IOS|IPHONE/.test(String(g.platform))) && g.placementProfileGroupId) ids.add(String(g.placementProfileGroupId)); return [...ids]; } diff --git a/cli/apple/screenshots.ts b/cli/apple/screenshots.ts index fc2adb6..de2f3fe 100644 --- a/cli/apple/screenshots.ts +++ b/cli/apple/screenshots.ts @@ -96,8 +96,9 @@ export async function run(ctx: Ctx): Promise { const version = await c.editableVersion(platform); if (!version) throw new Error(`no editable ${platformLabel(platform)} App Store version (run apple listing --version x.y.z first)`); log('apple', `screenshots for version ${versionLabel(version)}`); - const duo = platform === 'MAC_OS' ? [] : duoDirs(config.apple); - const duoGroupId = duo.length ? await duoGroup(c) : ''; + let duo = platform === 'MAC_OS' ? [] : duoDirs(config.apple); + // a Duo problem never stops the other sets + const duoGroupId = duo.length ? await duoGroup(c).catch((e: Error) => { warn('apple', `iPhone Duo skipped: ${e.message}`); duo = []; return ''; }) : ''; const appId = duo.length ? await c.app() : ''; if (platform === 'MAC_OS' && !config.apple?.mac) throw new Error('macOS version: set apple.mac: true and render the mac size (storebound shots render --size mac) first'); if (platform !== 'MAC_OS' && config.apple?.mac) log('apple', 'Mac screenshots (mac/, APP_DESKTOP) go to the macOS version: run apple screenshots --platform macos'); @@ -129,7 +130,7 @@ export async function run(ctx: Ctx): Promise { if (duo.length) { const files = duo.flatMap(dir => numberedImages(join(src, lang.id, dir)).filter(f => f.endsWith('.png'))); if (!files.length) warn('apple', `${locale}: nothing in ${duo.map(d => join(src, lang.id, d)).join(' or ')}, iPhone Duo skipped`); - else await syncDuo(c, { appId, group: duoGroupId, loc, files, dry: ctx.args.has('dry') }); + else await syncDuo(c, { appId, group: duoGroupId, loc, files, dry: ctx.args.has('dry') }).catch((e: Error) => { warn('apple', `${locale} iPhone Duo: ${e.message}`); process.exitCode = 1; }); } }); } diff --git a/tests/ppo.test.ts b/tests/ppo.test.ts index 3770a30..0d147fa 100644 --- a/tests/ppo.test.ts +++ b/tests/ppo.test.ts @@ -104,6 +104,7 @@ describe('iPhone Duo (foldable) sizes', () => { { placementProfileGroupId: 'g-mac', platform: 'MAC_OS', displayClassId: 'IPHONE_DUO' }] } }]; expect(duoGroups(ref)).toEqual(['g-duo']); expect(duoGroups([])).toEqual([]); + expect(duoGroups([{ attributes: { placementProfileGroups: [{ placementProfileGroupId: 'IPHONE_DUO_PROFILE', platform: 'IPHONE_APP_STORE', displayClassId: 'IPHONE_DUO' }] } }])).toEqual(['IPHONE_DUO_PROFILE']); expect(duoUpToDate(['a', 'b'], ['a', 'b'])).toBe(true); expect(duoUpToDate(['b', 'a'], ['a', 'b'])).toBe(false); expect(duoUpToDate(['a', undefined], ['a', 'b'])).toBe(false);