@@ -60,13 +60,6 @@ export async function GetOrSetXcodeVersion(): Promise<SemVer> {
6060 if ( installedXcodeVersions . length === 0 || ! xcodeVersionString . includes ( 'latest' ) ) {
6161 if ( installedXcodeVersions . length === 0 || ! installedXcodeVersions . includes ( xcodeVersionString ) ) {
6262 throw new Error ( `Xcode version ${ xcodeVersionString } is not installed! You will need to install this is a step before this one.` ) ;
63- } else {
64- core . info ( `Selecting installed Xcode version ${ xcodeVersionString } ...` ) ;
65- const selectExitCode = await exec ( 'xcodes' , [ 'select' , xcodeVersionString ] ) ;
66-
67- if ( selectExitCode !== 0 ) {
68- throw new Error ( `Failed to select Xcode version ${ xcodeVersionString } !` ) ;
69- }
7063 }
7164 } else {
7265 // Exclude versions containing 'Beta' and select the latest version
@@ -77,12 +70,13 @@ export async function GetOrSetXcodeVersion(): Promise<SemVer> {
7770 }
7871
7972 xcodeVersionString = nonBetaVersions [ nonBetaVersions . length - 1 ] ;
80- core . info ( `Selecting latest installed Xcode version ${ xcodeVersionString } ...` ) ;
81- const selectExitCode = await exec ( 'xcodes' , [ 'select' , xcodeVersionString ] ) ;
73+ }
8274
83- if ( selectExitCode !== 0 ) {
84- throw new Error ( `Failed to select Xcode version ${ xcodeVersionString } !` ) ;
85- }
75+ core . info ( `Selecting latest installed Xcode version ${ xcodeVersionString } ...` ) ;
76+ const selectExitCode = await exec ( 'xcodes' , [ 'select' , xcodeVersionString ] ) ;
77+
78+ if ( selectExitCode !== 0 ) {
79+ throw new Error ( `Failed to select Xcode version ${ xcodeVersionString } !` ) ;
8680 }
8781 }
8882
@@ -160,15 +154,13 @@ export async function GetProjectDetails(credential: AppleCredential, xcodeVersio
160154 core . info ( `Platform: ${ platform } ` ) ;
161155
162156 if ( platform !== 'macOS' ) {
163- const platformInstalled = await isPlatformInstalled ( platform ) ;
157+ const platformInstalled = await isSdkPlatformInstalled ( platform ) ;
158+ const platformSdkVersion = await getPlatformSdkVersion ( buildSettings ) ;
159+ const hasSimulators = await checkSimulatorsAvailable ( platform ) ;
164160
165- if ( ! platformInstalled ) {
166- await downloadPlatform ( platform ) ;
161+ if ( ! platformInstalled || ! hasSimulators ) {
162+ await downloadPlatformAndSdk ( platform , platformSdkVersion ) ;
167163 }
168-
169- await checkSimulatorsAvailable ( platform ) ;
170- const platformSdkVersion = await getPlatformSdkVersion ( buildSettings ) ;
171- await downloadPlatformSdkIfMissing ( platform , platformSdkVersion ) ;
172164 }
173165
174166 const configuration = core . getInput ( 'configuration' ) || 'Release' ;
@@ -355,7 +347,7 @@ export async function GetProjectDetails(credential: AppleCredential, xcodeVersio
355347 return projectRef ;
356348}
357349
358- async function checkSimulatorsAvailable ( platform : string ) : Promise < void > {
350+ async function checkSimulatorsAvailable ( platform : string ) : Promise < Boolean > {
359351 const destinationArgs = [ 'simctl' , 'list' , 'devices' , '--json' ] ;
360352
361353 if ( ! core . isDebug ( ) ) {
@@ -378,11 +370,7 @@ async function checkSimulatorsAvailable(platform: string): Promise<void> {
378370 . filter ( key => key . toLowerCase ( ) . includes ( platform . toLowerCase ( ) ) )
379371 . flatMap ( key => devices [ key ] ) ;
380372
381- if ( platformDevices . length > 0 ) {
382- return ;
383- }
384-
385- await downloadPlatform ( platform ) ;
373+ return platformDevices . length > 0 ;
386374}
387375
388376async function getSupportedPlatform ( projectPath : string ) : Promise < string > {
@@ -459,10 +447,12 @@ async function getPlatformSdkVersion(buildSettingsOutput: string): Promise<strin
459447 return platformSdkVersion ;
460448}
461449
462- async function isPlatformInstalled ( platform : string ) : Promise < boolean > {
450+ async function isSdkPlatformInstalled ( platform : string ) : Promise < boolean > {
463451 // Check if the platform SDK is available using xcodebuild -showsdks
464452 const output = await execXcodeBuild ( [ '-showsdks' ] ) ;
465453
454+ core . info ( `SDKs available:\n${ output } ` ) ;
455+
466456 // Example output line: "iOS SDKs:\n\tiOS 17.0 -sdk iphoneos17.0"
467457 const sdkMap : Record < string , string > = {
468458 'iOS' : 'iphoneos' ,
@@ -471,20 +461,20 @@ async function isPlatformInstalled(platform: string): Promise<boolean> {
471461 'visionOS' : 'xros' ,
472462 } ;
473463 const sdkString = sdkMap [ platform ] ;
464+
474465 if ( ! sdkString ) { return false ; }
475466 return output . includes ( `-sdk ${ sdkString } ` ) ;
476467}
477468
478- async function downloadPlatform ( platform : string ) {
479- await execXcodeBuild ( [ '-downloadPlatform' , platform ] ) ;
480- }
481-
482- async function downloadPlatformSdkIfMissing ( platform : string , version : string | null ) {
483- await exec ( 'xcodes' , [ 'runtimes' ] ) ;
484-
485- if ( version ) {
486- await exec ( 'xcodes' , [ 'runtimes' , 'install' , `${ platform } ${ version } ` ] ) ;
469+ async function downloadPlatformAndSdk ( platform : string , version : string ) : Promise < void > {
470+ const downloadDir = `${ process . env . RUNNER_TEMP } /xcodes/${ platform } -${ version } ` ;
471+ await execXcodeBuild ( [ '-downloadPlatform' , platform , '-buildVersion' , version , '-exportPath' , downloadDir ] ) ;
472+ const dmgPath = await getFirstPathWithGlob ( `${ downloadDir } /**/*.dmg` ) ;
473+ if ( ! dmgPath ) {
474+ throw new Error ( `Failed to find downloaded .dmg for platform ${ platform } version ${ version } ` ) ;
487475 }
476+ await fs . promises . access ( dmgPath , fs . constants . X_OK ) ;
477+ await execXcodeBuild ( [ '-importPlatform' , dmgPath ] ) ;
488478}
489479
490480async function getProjectScheme ( projectPath : string ) : Promise < string > {
0 commit comments