Skip to content

[eas-cli] Fix metadata:push silently skipping screenshot reorder when set already matches by (filename, fileSize)#3694

Open
Maples7 wants to merge 1 commit into
expo:mainfrom
Maples7:fix/screenshot-set-includes-appscreenshots
Open

[eas-cli] Fix metadata:push silently skipping screenshot reorder when set already matches by (filename, fileSize)#3694
Maples7 wants to merge 1 commit into
expo:mainfrom
Maples7:fix/screenshot-set-includes-appscreenshots

Conversation

@Maples7
Copy link
Copy Markdown

@Maples7 Maples7 commented May 8, 2026

Why

Refs #3690. Closes #3690.

eas metadata:push can finish reporting success while App Store Connect still shows screenshots in a different order than the local store.config.json. This happens when every (filename, fileSize) pair in a screenshot set already matches what's live, so eas-cli skips upload — but the reorder step that should still run is silently a no-op, locking in whatever order ASC currently has (often stale from an earlier transient failure).

Root cause

In packages/eas-cli/src/metadata/apple/tasks/screenshots.ts, after the upload pass, eas-cli refreshes the set to read the live order:

const refreshedSet = await AppScreenshotSet.infoAsync(localization.context, {
  id: screenshotSet.id,
});
const refreshedScreenshots = refreshedSet.attributes.appScreenshots || [];

AppScreenshotSet.infoAsync is defined in @expo/apple-utils (≤ 2.1.21) without a defaultQuery, so the underlying request is GET /v1/appScreenshotSets/{id} with no ?include=appScreenshots.

I verified empirically against a live ASC app:

Call relationships.appScreenshots.data
GET /v1/appScreenshotSets/{id} (no ?include) completely missing
GET /v1/appScreenshotSets/{id}?include=appScreenshots 10 entries, canonical order
GET /v1/appScreenshotSets/{id}/relationships/appScreenshots 10 entries, canonical order

The JSON:API parser in @expo/apple-utils skips relationships with no data:

for (const [t, a] of Object.entries(r)) {
  const r = a?.data;
  if (!r) continue;   // ← include omitted → data undefined → relationship dropped
  ...
}

So refreshedSet.attributes.appScreenshots ends up undefinedrefreshedScreenshots = []screenshotsByFilename is empty → orderedIds is empty → the if (orderedIds.length > 0 && …) reorder guard is never satisfied → reorderScreenshotsAsync is never called → live order stays stale.

It's worth noting AppStoreVersionLocalization.getAppScreenshotSetsAsync (the call eas-cli uses to populate the initial screenshotSets map in prepareAsync) hardcodes includes: [..., 'appScreenshots'], which is why everything else in this file works. Only the post-upload refresh was affected.

How

AppScreenshotSet.infoAsync accepts query?: ConnectQueryParams, so we can compensate from eas-cli without waiting for an @expo/apple-utils release:

const refreshedSet = await AppScreenshotSet.infoAsync(localization.context, {
  id: screenshotSet.id,
  query: { includes: ['appScreenshots'] },
});

The longer-term fix is to add defaultQuery: { includes: ['appScreenshots'] } to AppScreenshotSet.infoAsync inside @expo/apple-utils (it's already done for similar models like CustomerReview, which uses DEFAULT_INCLUDES). I'm filing that suggestion separately on #3690 so the maintainers of the package can route it.

Test Plan

  • Added a regression test in screenshots.test.ts:
    • asserts AppScreenshotSet.infoAsync is called with query: { includes: ['appScreenshots'] },
    • simulates a live store whose order is reversed compared to the local config,
    • asserts reorderScreenshotsAsync is called with the desired order.

Local results:

  • yarn build → green (lerna build for 13 projects).
  • yarn lint → no new errors (12 pre-existing warnings unrelated to this change).
  • yarn jest --testPathPattern='metadata'191 / 191 passing (16 suites).

/changelog-entry bug-fix [eas-cli] Fix metadata:push silently skipping screenshot reorder when every (filename, fileSize) already matches the live set.

…so reorder is not silently skipped

`AppScreenshotSet.infoAsync` from @expo/apple-utils does not pass an
`includes` query by default, so the App Store Connect API responds without
`relationships.appScreenshots.data` and `attributes.appScreenshots` ends up
undefined. The reorder check below then sees an empty list and silently
skips the PATCH — leaving the live store with a stale order even though
every (filename, fileSize) pair already matches the local config and no
upload was needed.

Pass `query: { includes: [`appScreenshots`] }` explicitly so the refresh
returns the canonical relationship data and reorder runs when needed.

Refs expo#3690.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Subscribed to pull request

File Patterns Mentions
**/* @douglowder
packages/eas-cli/src/metadata/** @byCedric

Generated by CodeMention

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

metadata:push: screenshot reorder is skipped while App Store Connect order still differs from store.config.json

1 participant