Skip to content

Commit 3cb122b

Browse files
update sdk download strategy
1 parent 2178992 commit 3cb122b

File tree

4 files changed

+70
-95
lines changed

4 files changed

+70
-95
lines changed

dist/index.js

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -58368,6 +58368,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
5836858368
exports.log = log;
5836958369
exports.DeepEqual = DeepEqual;
5837058370
exports.matchRegexPattern = matchRegexPattern;
58371+
exports.getPathsWithGlob = getPathsWithGlob;
5837158372
exports.getFirstPathWithGlob = getFirstPathWithGlob;
5837258373
exports.getFileContents = getFileContents;
5837358374
const core = __nccwpck_require__(2186);
@@ -58439,6 +58440,14 @@ function matchRegexPattern(string, pattern, group) {
5843958440
}
5844058441
return group ? (_a = match.groups) === null || _a === void 0 ? void 0 : _a[group] : match[1];
5844158442
}
58443+
async function getPathsWithGlob(globPattern) {
58444+
const globber = await glob.create(globPattern);
58445+
const files = await globber.glob();
58446+
if (files.length === 0) {
58447+
throw new Error(`No file found at: ${globPattern}`);
58448+
}
58449+
return files;
58450+
}
5844258451
async function getFirstPathWithGlob(globPattern) {
5844358452
const globber = await glob.create(globPattern);
5844458453
const files = await globber.glob();
@@ -58596,10 +58605,9 @@ async function GetProjectDetails(credential, xcodeVersion) {
5859658605
const platform = await getSupportedPlatform(projectPath);
5859758606
core.info(`Platform: ${platform}`);
5859858607
if (platform !== 'macOS') {
58599-
const platformInstalled = await isSdkPlatformInstalled(platform);
5860058608
const platformSdkVersion = await getPlatformSdkVersion(buildSettings);
58601-
const hasSimulators = await checkSimulatorsAvailable(platform);
58602-
if (!platformInstalled || !hasSimulators) {
58609+
const platformSdk = await getSdkInfo(platform, platformSdkVersion);
58610+
if (!platformSdk) {
5860358611
await downloadPlatformAndSdk(platform, platformSdkVersion);
5860458612
}
5860558613
}
@@ -58754,27 +58762,6 @@ async function GetProjectDetails(credential, xcodeVersion) {
5875458762
infoPlistContent = await (0, utilities_1.getFileContents)(infoPlistPath);
5875558763
return projectRef;
5875658764
}
58757-
async function checkSimulatorsAvailable(platform) {
58758-
const destinationArgs = ['simctl', 'list', 'devices', '--json'];
58759-
if (!core.isDebug()) {
58760-
core.info(`[command]${xcrun} ${destinationArgs.join(' ')}`);
58761-
}
58762-
let output = '';
58763-
await (0, exec_1.exec)(xcrun, destinationArgs, {
58764-
listeners: {
58765-
stdout: (data) => {
58766-
output += data.toString();
58767-
}
58768-
},
58769-
silent: !core.isDebug()
58770-
});
58771-
const response = JSON.parse(output);
58772-
const devices = response.devices;
58773-
const platformDevices = Object.keys(devices)
58774-
.filter(key => key.toLowerCase().includes(platform.toLowerCase()))
58775-
.flatMap(key => devices[key]);
58776-
return platformDevices.length > 0;
58777-
}
5877858765
async function getSupportedPlatform(projectPath) {
5877958766
const projectFilePath = `${projectPath}/project.pbxproj`;
5878058767
core.debug(`.pbxproj file path: ${projectFilePath}`);
@@ -58833,30 +58820,23 @@ async function getPlatformSdkVersion(buildSettingsOutput) {
5883358820
core.info(`Platform SDK version: ${platformSdkVersion}`);
5883458821
return platformSdkVersion;
5883558822
}
58836-
async function isSdkPlatformInstalled(platform) {
58837-
const output = await execXcodeBuild(['-showsdks']);
58838-
core.info(`SDKs available:\n${output}`);
58839-
const sdkMap = {
58840-
'iOS': 'iphoneos',
58841-
'tvOS': 'appletvos',
58842-
'watchOS': 'watchos',
58843-
'visionOS': 'xros',
58844-
};
58845-
const sdkString = sdkMap[platform];
58846-
if (!sdkString) {
58847-
return false;
58848-
}
58849-
return output.includes(`-sdk ${sdkString}`);
58823+
async function getSdkInfo(platform, version) {
58824+
const output = await execXcodeBuild(['-showsdks', '-json']);
58825+
core.info(`Installed SDKs:\n${output}`);
58826+
const installedSdks = JSON.parse(output);
58827+
const sdk = installedSdks.find(sdk => sdk.platform.toLowerCase() === platform.toLowerCase() && sdk.sdkVersion.toString() === version);
58828+
core.info(`Found SDK:\n${sdk ? JSON.stringify(sdk) : ''}`);
58829+
return sdk || null;
5885058830
}
5885158831
async function downloadPlatformAndSdk(platform, version) {
5885258832
const downloadDir = `${process.env.RUNNER_TEMP}/xcodes/${platform}-${version}`;
58853-
await execXcodeBuild(['-downloadPlatform', platform, '-buildVersion', version, '-exportPath', downloadDir]);
58854-
const dmgPath = await (0, utilities_1.getFirstPathWithGlob)(`${downloadDir}/**/*.dmg`);
58855-
if (!dmgPath) {
58856-
throw new Error(`Failed to find downloaded .dmg for platform ${platform} version ${version}`);
58833+
await execXcodeBuild(['-downloadPlatform', platform, '-exportPath', downloadDir, '-buildVersion', version]);
58834+
const dmgPaths = await (0, utilities_1.getPathsWithGlob)(`${downloadDir}/**/*.dmg`);
58835+
core.info(`Downloaded DMG paths:\n${dmgPaths.join('\n')}`);
58836+
for (const dmgPath of dmgPaths) {
58837+
await fs.promises.access(dmgPath, fs.constants.R_OK);
58838+
await execXcodeBuild(['-importPlatform', dmgPath]);
5885758839
}
58858-
await fs.promises.access(dmgPath, fs.constants.X_OK);
58859-
await execXcodeBuild(['-importPlatform', dmgPath]);
5886058840
}
5886158841
async function getProjectScheme(projectPath) {
5886258842
let scheme = core.getInput('scheme');

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/utilities.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,33 @@ export function DeepEqual(a: any, b: any): boolean {
5555

5656
export function matchRegexPattern(string: string, pattern: RegExp, group: string | null): string {
5757
const match = string.match(pattern);
58+
5859
if (!match) {
5960
throw new Error(`Failed to resolve: ${pattern}`);
6061
}
62+
6163
return group ? match.groups?.[group] : match[1];
6264
}
6365

66+
export async function getPathsWithGlob(globPattern: string): Promise<string[]> {
67+
const globber = await glob.create(globPattern);
68+
const files = await globber.glob();
69+
70+
if (files.length === 0) {
71+
throw new Error(`No file found at: ${globPattern}`);
72+
}
73+
74+
return files;
75+
}
76+
6477
export async function getFirstPathWithGlob(globPattern: string): Promise<string> {
6578
const globber = await glob.create(globPattern);
6679
const files = await globber.glob();
80+
6781
if (files.length === 0) {
6882
throw new Error(`No file found at: ${globPattern}`);
6983
}
84+
7085
return files[0];
7186
}
7287

src/xcode.ts

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
log,
1313
matchRegexPattern,
1414
getFirstPathWithGlob,
15-
getFileContents
15+
getFileContents,
16+
getPathsWithGlob
1617
} from './utilities';
1718
import { SemVer } from 'semver';
1819
import core = require('@actions/core');
@@ -154,11 +155,10 @@ export async function GetProjectDetails(credential: AppleCredential, xcodeVersio
154155
core.info(`Platform: ${platform}`);
155156

156157
if (platform !== 'macOS') {
157-
const platformInstalled = await isSdkPlatformInstalled(platform);
158158
const platformSdkVersion = await getPlatformSdkVersion(buildSettings);
159-
const hasSimulators = await checkSimulatorsAvailable(platform);
159+
const platformSdk = await getSdkInfo(platform, platformSdkVersion);
160160

161-
if (!platformInstalled || !hasSimulators) {
161+
if (!platformSdk) {
162162
await downloadPlatformAndSdk(platform, platformSdkVersion);
163163
}
164164
}
@@ -347,32 +347,6 @@ export async function GetProjectDetails(credential: AppleCredential, xcodeVersio
347347
return projectRef;
348348
}
349349

350-
async function checkSimulatorsAvailable(platform: string): Promise<Boolean> {
351-
const destinationArgs = ['simctl', 'list', 'devices', '--json'];
352-
353-
if (!core.isDebug()) {
354-
core.info(`[command]${xcrun} ${destinationArgs.join(' ')}`);
355-
}
356-
357-
let output = '';
358-
await exec(xcrun, destinationArgs, {
359-
listeners: {
360-
stdout: (data: Buffer) => {
361-
output += data.toString();
362-
}
363-
},
364-
silent: !core.isDebug()
365-
});
366-
367-
const response = JSON.parse(output);
368-
const devices = response.devices;
369-
const platformDevices = Object.keys(devices)
370-
.filter(key => key.toLowerCase().includes(platform.toLowerCase()))
371-
.flatMap(key => devices[key]);
372-
373-
return platformDevices.length > 0;
374-
}
375-
376350
async function getSupportedPlatform(projectPath: string): Promise<string> {
377351
const projectFilePath = `${projectPath}/project.pbxproj`;
378352
core.debug(`.pbxproj file path: ${projectFilePath}`);
@@ -447,34 +421,40 @@ async function getPlatformSdkVersion(buildSettingsOutput: string): Promise<strin
447421
return platformSdkVersion;
448422
}
449423

450-
async function isSdkPlatformInstalled(platform: string): Promise<boolean> {
451-
// Check if the platform SDK is available using xcodebuild -showsdks
452-
const output = await execXcodeBuild(['-showsdks']);
424+
type SdkInfo = {
425+
canonicalName: string;
426+
displayName: string;
427+
isBaseSdk: boolean;
428+
platform: string;
429+
platformPath: string;
430+
platformVersion: string;
431+
sdkPath: string;
432+
sdkVersion: string;
433+
}
453434

454-
core.info(`SDKs available:\n${output}`);
435+
async function getSdkInfo(platform: string, version: string): Promise<SdkInfo | null> {
436+
// Check if the platform SDK is available using xcodebuild -showsdks
437+
const output = await execXcodeBuild(['-showsdks', '-json']);
455438

456-
// Example output line: "iOS SDKs:\n\tiOS 17.0 -sdk iphoneos17.0"
457-
const sdkMap: Record<string, string> = {
458-
'iOS': 'iphoneos',
459-
'tvOS': 'appletvos',
460-
'watchOS': 'watchos',
461-
'visionOS': 'xros',
462-
};
463-
const sdkString = sdkMap[platform];
439+
core.info(`Installed SDKs:\n${output}`);
464440

465-
if (!sdkString) { return false; }
466-
return output.includes(`-sdk ${sdkString}`);
441+
const installedSdks = JSON.parse(output) as Array<SdkInfo>;
442+
const sdk = installedSdks.find(sdk => sdk.platform.toLowerCase() === platform.toLowerCase() && sdk.sdkVersion.toString() === version);
443+
core.info(`Found SDK:\n${sdk ? JSON.stringify(sdk) : ''}`);
444+
return sdk || null;
467445
}
468446

469447
async function downloadPlatformAndSdk(platform: string, version: string): Promise<void> {
470448
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}`);
449+
await execXcodeBuild(['-downloadPlatform', platform, '-exportPath', downloadDir, '-buildVersion', version]);
450+
const dmgPaths = await getPathsWithGlob(`${downloadDir}/**/*.dmg`);
451+
452+
core.info(`Downloaded DMG paths:\n${dmgPaths.join('\n')}`);
453+
454+
for (const dmgPath of dmgPaths) {
455+
await fs.promises.access(dmgPath, fs.constants.R_OK);
456+
await execXcodeBuild(['-importPlatform', dmgPath]);
475457
}
476-
await fs.promises.access(dmgPath, fs.constants.X_OK);
477-
await execXcodeBuild(['-importPlatform', dmgPath]);
478458
}
479459

480460
async function getProjectScheme(projectPath: string): Promise<string> {

0 commit comments

Comments
 (0)