Skip to content

[snapshot] use simulator UDIDs for destinations#30054

Merged
iBotPeaches merged 2 commits into
fastlane:masterfrom
philprime:fix/snapshot-simulator-destination-id
May 29, 2026
Merged

[snapshot] use simulator UDIDs for destinations#30054
iBotPeaches merged 2 commits into
fastlane:masterfrom
philprime:fix/snapshot-simulator-destination-id

Conversation

@philprime

@philprime philprime commented May 29, 2026

Copy link
Copy Markdown
Contributor

Checklist

  • I've run bundle exec rspec from the root directory to see all new and existing tests pass
  • I've followed the fastlane code style and run bundle exec rubocop -a to ensure the code style is valid
  • I see several green ci/circleci builds in the "All checks have passed" section of my PR (connect CircleCI to GitHub if not)
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary.
  • I've added or updated relevant unit tests.

Motivation and Context

snapshot already prepares simulators by resolving a concrete simulator UDID. For example, it opens Simulator and runs simctl commands against that UDID:

open -a Simulator.app --args -CurrentDeviceUDID F24194FE-5DD3-470D-991D-6A91C456657A
xcrun simctl uninstall F24194FE-5DD3-470D-991D-6A91C456657A com.techprimate.Flinky

But the generated xcodebuild command did not use that same UDID. It emitted a separate platform,name,OS destination:

xcodebuild \
  -scheme ScreenshotUITests \
  -project ./Flinky.xcodeproj \
  -configuration Debug \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=26.4' \
  FASTLANE_SNAPSHOT=YES \
  FASTLANE_LANGUAGE=en-US \
  build test

That can fail when CoreSimulator and xcodebuild disagree about the string OS version for the same simulator runtime. In the observed CI failure, snapshot prepared an iPhone 17 Pro simulator by UDID, but xcodebuild failed to resolve OS=26.4:

xcodebuild: error: Unable to find a device matching the provided destination specifier:
		{ platform:iOS Simulator, OS:26.4, name:iPhone 17 Pro }

The requested device could not be found because no available devices matched the request.

The available destinations in that job included iPhone 17 Pro devices for OS:26.4.1 and OS:26.5, but not OS:26.4.

CI references:

Description

This changes the modern snapshot test command generator to pass the resolved simulator UDID to xcodebuild:

-destination 'platform=iOS Simulator,id=<resolved simulator UDID>'

The important part is that xcodebuild now receives the same simulator identity that snapshot uses during simulator preparation. This avoids a second destination lookup by name and OS, which can select no device or a different device when runtime metadata is inconsistent.

The local reproduction environment had both iOS 26.4 and iOS 26.4.1 runtimes installed. simctl list runtimes reported both under the same display runtime name and identifier:

iOS 26.4 (26.4 - 23E244) - com.apple.CoreSimulator.SimRuntime.iOS-26-4
iOS 26.4 (26.4.1 - 23E254a) - com.apple.CoreSimulator.SimRuntime.iOS-26-4

simctl list devices then printed duplicate -- iOS 26.4 -- sections, while xcodebuild -showdestinations reported the same simulator UDID as OS:26.4.1:

{ platform:iOS Simulator, arch:arm64, id:B49A866F-9928-4BE5-B64C-43057EB05198, OS:26.4.1, name:iPhone 17 Pro }

Using a UDID destination avoids depending on the mismatched OS string.

This also keeps explicit ios_version behavior: if a user configures ios_version, snapshot still uses that version when resolving the simulator. The change removes the implicit LatestOsVersion.version(os) lookup from the default destination path so the generated xcodebuild command uses the same default simulator lookup contract as the preparation steps. Without that, snapshot could still prepare one UDID and run tests on another one.

The older Xcode 8 generator already used a UDID destination. This aligns the modern generator with that approach.

Regression coverage was added for:

  • generated destinations using id=<udid> instead of name=<name>,OS=<version>;
  • the generated xcodebuild destination matching TestCommandGenerator.device_udid;
  • iOS, tvOS, and watchOS command expectations using UDID destinations.

Testing Steps

Focused destination regression specs:

bundle exec rspec \
  snapshot/spec/test_command_generator_spec.rb:31 \
  snapshot/spec/test_command_generator_spec.rb:42 \
  snapshot/spec/test_command_generator_spec.rb:52

Broader command-generator specs:

bundle exec rspec \
  snapshot/spec/test_command_generator_spec.rb \
  snapshot/spec/test_command_generator_xcode_8_spec.rb

Manual destination reproduction:

xcodebuild -showBuildSettings \
  -scheme ScreenshotUITests \
  -project ./Flinky.xcodeproj \
  -configuration Debug \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=26.4'

Observed result:

xcodebuild: error: Could not configure request to show build settings: Unable to find a device matching the provided destination specifier:
		{ platform:iOS Simulator, OS:26.4, name:iPhone 17 Pro }

The same request succeeds when addressed by concrete UDID:

xcodebuild -showBuildSettings \
  -scheme ScreenshotUITests \
  -project ./Flinky.xcodeproj \
  -configuration Debug \
  -destination 'platform=iOS Simulator,id=FC42BA48-38ED-4A94-8E96-5512C25BB0F9'

Observed result includes:

TARGET_DEVICE_IDENTIFIER = FC42BA48-38ED-4A94-8E96-5512C25BB0F9
TARGET_DEVICE_OS_VERSION = 26.5

fixes: #29553
fixes: #29481
fixes: #30040
fixes: #22284

philprime added 2 commits May 29, 2026 10:59
Generate modern snapshot xcodebuild destinations with the resolved simulator UDID so test execution targets the same simulator that preparation steps modified.

Document the iOS 26.4 runtime mismatch investigation and reproduction notes.
@philprime philprime changed the title Fix/snapshot simulator destination [snapshot] select simulator destination by udid May 29, 2026
@philprime philprime changed the title [snapshot] select simulator destination by udid [snapshot] use simulator UDIDs for destinations May 29, 2026
@iBotPeaches

Copy link
Copy Markdown
Member

@philprime

Copy link
Copy Markdown
Contributor Author

@iBotPeaches Yes, as far as I can tell from looking at the issue descriptions this fix should solve all of them.

@iBotPeaches

Copy link
Copy Markdown
Member

Thanks. Just trying to comb some history to see why we moved away from the UDID in first place, since to your point it seems in way older code it was that way already.

@iBotPeaches iBotPeaches merged commit 43dc4fa into fastlane:master May 29, 2026
9 checks passed

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @philprime 👋

Thank you for your contribution to fastlane and congrats on getting this pull request merged 🎉
The code change now lives in the master branch, however it wasn't released to RubyGems yet.
We usually ship about once a month, and your PR will be included in the next one.

Please let us know if this change requires an immediate release by adding a comment here 👍
We'll notify you once we shipped a new release with your changes 🚀"

@fulldecent

Copy link
Copy Markdown
Contributor

@philprime Thank you! This approach is airtight and fixes all different kinds of problems that we have seen for looking up by name.

@philprime

Copy link
Copy Markdown
Contributor Author

Happy to help! 😃

@philprime philprime deleted the fix/snapshot-simulator-destination-id branch May 29, 2026 14:22

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations! 🎉 This was released as part of fastlane 2.236.0 🚀

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

Projects

None yet

3 participants