Update dotnet/macios to a new Xcode beta and validate it end-to-end. Use this skill when a user asks to bump Xcode beta versions, update macios SDK/version constants, run xtro-sharpie sanitization, and run introspection tests for iOS/tvOS/macOS/Mac Catalyst.
75
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Run this workflow from the macios repository root.
Collect or confirm:
26.4)2)26.4.0-beta.2)17E5212f)https://dl.internalx.com/internal-files/xcodes/Xcode_26.4_beta_2.xip)If a prior PR is provided, mirror its file-touch pattern and intentionally skip/add tests based on user scope.
Apply minimal, surgical changes in these files:
Make.config
NUGET_HARDCODED_PRERELEASE_IDENTIFIER=xcode<major.minor>NUGET_HARDCODED_PRERELEASE_BRANCH=xcode<major.minor>XCODE_VERSION=<major.minor>XCODE_PACKAGE_NAME=xcode-apple-siliconXCODE_PACKAGE_VERSION=<major.minor.patch-beta.number>XCODE_BUILD_VERSION=<ProductBuildVersion>XCODE_URL=<user-provided-xip-url>XCODE_DEVELOPER_ROOT=/Applications/Xcode_<major.minor>.0-beta<beta>.app/Contents/Developer (for betas)XCODE_DEVELOPER_ROOT must name the same application that XCODE_PACKAGE_VERSION
implies; install-xcode.sh refuses to run when the two disagree. The package version is
strict SemVer (Azure Artifacts requires it) while the application name follows this
repository's convention, so they are deliberately spelled differently:
| Release | XCODE_PACKAGE_VERSION | XCODE_DEVELOPER_ROOT application |
|---|---|---|
| beta 1 | 27.0.0-beta | Xcode_27.0.0-beta.app |
| beta 3 | 27.0.0-beta.3 | Xcode_27.0.0-beta3.app |
| RC 1 | 27.0.0-rc | Xcode_27.0.0-rc.app |
| RC 2 | 27.0.0-rc.2 | Xcode_27.0.0-rc.2.app |
| stable | 27.0.0 | Xcode_27.0.0.app |
| patch | 27.0.1 | Xcode_27.0.1.app (XCODE_VERSION stays 27.0) |
Betas drop the dot before the ordinal, release candidates keep it, and the first beta or
RC carries no ordinal at all. Xcode_26.3.0-rc2.app is wrong: it has been written twice
and corrected both times. Note that XCODE_BUILD_VERSION is what actually distinguishes
one beta or RC from the next, so a stale value passes every path check and only fails
once the package is installed.
Before queuing CI, verify that the matching immutable package exists — with its
Apple-signed XIP and xcode-metadata.json — in both feeds, because the two
pipelines resolve the same coordinates in their own organization:
devdiv/DevDiv/macios-tools-internaldnceng/internal/macios-tools-internalMake.versions
IOS_NUGET_OS_VERSIONTVOS_NUGET_OS_VERSIONMACOS_NUGET_OS_VERSIONMACCATALYST_NUGET_OS_VERSIONbuilds/Versions-iOS.plist.in
builds/Versions-tvOS.plist.in
builds/Versions-macOS.plist.in
builds/Versions-MacCatalyst.plist.in
KnownVersions and SupportedTargetPlatformVersionsMacCatalystVersionMaptools/common/SdkVersions.cs
tools/devops/automation/templates/variables/common.yml
xcodeChannel to Beta for beta/RC buildsRun:
make show-versionsRun:
make worldDo not bypass Xcode component checks by default.
If check-system fails because MetalToolchain is missing, install it and rerun:
xcrun xcodebuild -downloadComponent MetalToolchain
make worldIf simulator runtimes are missing, provision and rerun:
./system-dependencies.sh --provision-simulators
make worldRun:
AUTO_SANITIZE=1 make -C tests/xtro-sharpie allIf it fails with unclassified entries, run:
make -C tests/xtro-sharpie unclassified2todo
AUTO_SANITIZE=1 make -C tests/xtro-sharpie allCapture resulting tests/xtro-sharpie/api-annotations-dotnet/*.todo and *.ignore changes.
Use explicit prebuild + run to avoid mobile run target issues.
IMPORTANT: Run platforms sequentially, not in parallel. The shared obj/ directories
(tests/common/Touch.Unit/Touch.Client/dotnet/obj and tests/common/MonoTouch.Dialog/obj)
cause NETSDK1005 errors when concurrent restores overwrite project.assets.json with
different platform TFMs. Clean shared obj dirs before each platform build:
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
make -C tests/introspection/dotnet build-ios run-ios
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
make -C tests/introspection/dotnet build-tvos run-tvos
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
make -C tests/introspection/dotnet build-macOS run-macOS
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
make -C tests/introspection/dotnet build-MacCatalyst run-MacCatalystDesktop test output: For macOS and Mac Catalyst, make run-macOS/run-MacCatalyst uses
dotnet build -t:Run which launches the app without waiting or capturing stdout. The make
command exits immediately with success even while tests are still running. To get actual test
results, run the executable directly after building:
# Build first
make -C tests/introspection/dotnet build-macOS
# Then run directly to capture output
NUNIT_AUTOSTART=true NUNIT_AUTOEXIT=true \
tests/introspection/dotnet/macOS/bin/Debug/net10.0-macos/osx-arm64/introspection.app/Contents/MacOS/introspectionSame pattern for Mac Catalyst (replace macOS → MacCatalyst, net10.0-macos → net10.0-maccatalyst, osx-arm64 → maccatalyst-arm64).
iOS and tvOS simulator tests capture output correctly via make run-ios/run-tvos.
These runs can take a long time; wait for completion and summarize outcomes per platform.
Before finishing, confirm all items:
make world succeeds without ignore flagsunclassified2todo if neededWhen reporting results, use this structure:
d259b5f
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.