[eas-cli] Fix metadata:pull discarding screenshots that share a file name - #4182
Open
giaBaoJS wants to merge 1 commit into
Open
[eas-cli] Fix metadata:pull discarding screenshots that share a file name#4182giaBaoJS wants to merge 1 commit into
giaBaoJS wants to merge 1 commit into
Conversation
|
Subscribed to pull request
Generated by CodeMention Warning: The preamble and epilogue options in commentConfiguration are deprecated. Use template instead. |
…al name on pull
App Store Connect does not enforce unique file names within a screenshot
set. `eas metadata:pull` resolved every screenshot to
`store/apple/screenshot/{locale}/{displayType}/{fileName}`, so screenshots
sharing a name all mapped to the same path: each download overwrote the
previous one and the config listed the same file several times, silently
losing screenshots.
Track the names already used within a set and add a numeric suffix
(`home.png`, `home-2.png`) to the duplicates, warning when a name is
changed. Names that do not collide are left untouched, so they keep
matching their App Store Connect counterpart when the config is pushed
back.
Fixes expo#3715
giaBaoJS
force-pushed
the
fix/metadata-pull-duplicate-screenshot-filenames
branch
from
August 18, 2026 15:05
96e9e60 to
0b60ed9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Fixes #3715.
eas metadata:pullsilently discards App Store screenshots that share a file name.App Store Connect does not enforce unique file names within a screenshot set, so two screenshots in the same set can both report e.g.
iPhone 5.5 - 2.png.downloadScreenshotAsyncresolved every screenshot tostore/apple/screenshot/{locale}/{displayType}/{fileName}, which means the duplicates all mapped to the same local path:Two things went wrong as a result:
writeFileoverwrote the previous screenshot, so only the last one survived on disk;store.config.jsonlisted the same file several times instead of listing each screenshot.Pulling a set of 3 screenshots that share a name left 1 file on disk and 3 identical entries in config. Pushing that config back then re-uploaded the same image in place of the others, so the screenshots were lost in App Store Connect too.
How
Track the file names already used within a single screenshot set and give the duplicates a numeric suffix before the extension (
home.png,home-2.png,home-3.png), warning when a name is changed so the mismatch with App Store Connect is discoverable.The suffix is applied only on a genuine collision. This matters because the push side matches local files to remote screenshots by file name (
syncScreenshotSetAsync), so renaming unconditionally would break that correspondence and cause spurious re-uploads and deletions on every push. Names that do not collide are passed through untouched.Uniqueness is scoped per screenshot set, which is exactly the directory the files land in — the same file name in a different display type or locale writes to a different directory and is left alone.
The suffixed name is also used for the placeholder path written when a screenshot is in a broken
AWAITING_UPLOADstate and cannot be downloaded, so those entries do not collapse either.Test Plan
packages/eas-cli/src/metadata/apple/tasks/__tests__/screenshots.test.tsgains six tests:downloadAsynckeeps original file names when they do not collide— asserts both the config entries and the exactwriteFilepaths keep the unmodified App Store Connect names. This pins down that the fix cannot degenerate into "always suffix".writes distinct files when screenshots share a file name— the regression test. Three screenshots namediPhone 5.5 - 2.pngnow produce three distinct config entries and three distinctwriteFilepaths, and the rename is warned about.does not add suffixes for the same file name in different sets— the same name inAPP_IPHONE_67andAPP_IPAD_PRO_3GEN_129writes to separate directories and is left as-is.deduplicates placeholder paths when broken screenshots share a file name— covers the non-download path.downloadAsync -> uploadAsync(round trip) — runs a pull and then pushes the config it produced back against the same remote set, to verify local↔remote file-name correspondence survives:pushes back a pulled config without re-uploading or deleting anything— with distinct remote names, push is a complete no-op: nothing uploaded, nothing deleted.only re-uploads the renamed duplicate when file names collide remotely— the entry that kept the original name still matches its remote counterpart and is untouched; only the suffixed duplicate is uploaded, and nothing is deleted.Verified by reverting the source change and keeping the tests: the three collision tests fail (config and
writeFileboth collapse to the duplicated path), and the two non-collision tests still pass. Restoring the change turns them green.Full
packages/eas-clisuite: 281/283 suites pass, 2399 passed / 4 skipped, +6 tests versus the tree without this change. The two failing suites (src/observe/__tests__/formatCustomEvents.test.ts,src/observe/__tests__/formatEvents.test.ts) fail identically before and after — they are locale-dependent snapshots unrelated to this change.yarn typecheck,yarn lintandyarn fmt:checkare clean.Note on scope
Push matching is keyed on the file name, so it cannot tell two identically named remote screenshots apart — the second one shadows the first in
existingByFilename. That is pre-existing and unchanged here; this PR is limited to makingmetadata:pullstop destroying the local files. Happy to follow up on the push-side matcher separately if that is wanted.