@expo/build-tools 18.7.0 → 18.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builders/ios.js +15 -2
- package/dist/common/easBuildInternal.js +3 -27
- package/dist/context.js +3 -1
- package/dist/ios/fastlane.d.ts +4 -1
- package/dist/ios/fastlane.js +9 -1
- package/dist/ios/gymfile.d.ts +5 -2
- package/dist/ios/gymfile.js +5 -2
- package/dist/steps/easFunctions.js +8 -0
- package/dist/steps/functionGroups/build.js +4 -0
- package/dist/steps/functions/configureIosCredentials.js +9 -3
- package/dist/steps/functions/configureIosVersion.js +32 -14
- package/dist/steps/functions/deploy.d.ts +2 -0
- package/dist/steps/functions/deploy.js +136 -0
- package/dist/steps/functions/eagerBundle.js +1 -1
- package/dist/steps/functions/export.d.ts +2 -0
- package/dist/steps/functions/export.js +115 -0
- package/dist/steps/functions/generateGymfileFromTemplate.js +9 -0
- package/dist/steps/functions/installNodeModules.js +1 -1
- package/dist/steps/functions/parseXcactivitylog.d.ts +2 -0
- package/dist/steps/functions/parseXcactivitylog.js +49 -0
- package/dist/steps/functions/prebuild.js +1 -1
- package/dist/steps/functions/restoreBuildCache.js +1 -1
- package/dist/steps/functions/saveBuildCache.js +1 -1
- package/dist/steps/functions/startAgentDeviceRemoteSession.d.ts +2 -0
- package/dist/steps/functions/startAgentDeviceRemoteSession.js +181 -0
- package/dist/steps/utils/ios/xcactivitylog.d.ts +57 -0
- package/dist/steps/utils/ios/xcactivitylog.js +278 -0
- package/dist/templates/GymfileArchive.d.ts +1 -1
- package/dist/templates/GymfileArchive.js +4 -0
- package/dist/templates/GymfileSimulator.d.ts +1 -1
- package/dist/templates/GymfileSimulator.js +3 -0
- package/dist/utils/easCli.d.ts +11 -0
- package/dist/utils/easCli.js +57 -0
- package/dist/utils/packageManager.d.ts +4 -1
- package/dist/utils/packageManager.js +13 -4
- package/package.json +4 -4
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseAndReportXcactivitylog = parseAndReportXcactivitylog;
|
|
7
|
+
exports.isCompileStep = isCompileStep;
|
|
8
|
+
exports.collectTopLevelCompileSteps = collectTopLevelCompileSteps;
|
|
9
|
+
exports.buildTargetMetrics = buildTargetMetrics;
|
|
10
|
+
exports.formatReport = formatReport;
|
|
11
|
+
const downloader_1 = __importDefault(require("@expo/downloader"));
|
|
12
|
+
const results_1 = require("@expo/results");
|
|
13
|
+
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
14
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
15
|
+
const os_1 = __importDefault(require("os"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const zod_1 = require("zod");
|
|
18
|
+
const DEFAULT_XCLOGPARSER_VERSION = 'v0.2.46';
|
|
19
|
+
const XCLOGPARSER_DOWNLOAD_URL = 'https://storage.googleapis.com/turtle-v2/xclogparser';
|
|
20
|
+
const XCLOGPARSER_DOWNLOAD_TIMEOUT_MS = 20_000;
|
|
21
|
+
const XCLOGPARSER_OUTPUT_FILENAME = 'xcactivitylog.json';
|
|
22
|
+
/**
|
|
23
|
+
* Download xclogparser, parse xcactivitylog from derived data, and log a
|
|
24
|
+
* compile metrics report. Never throws — all errors are logged at debug level.
|
|
25
|
+
*
|
|
26
|
+
* Can be called from both the step-based flow (BuildFunction) and the
|
|
27
|
+
* traditional builder flow (runBuildPhase).
|
|
28
|
+
*/
|
|
29
|
+
async function parseAndReportXcactivitylog({ derivedDataPath, workspacePath, xclogparserVersion = DEFAULT_XCLOGPARSER_VERSION, logger, proxyBaseUrl, }) {
|
|
30
|
+
let tempDir;
|
|
31
|
+
try {
|
|
32
|
+
tempDir = await fs_extra_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'xclogparser-'));
|
|
33
|
+
const xclogparserPath = await downloadXclogparser(tempDir, xclogparserVersion, logger, proxyBaseUrl);
|
|
34
|
+
const jsonOutputPath = await runXclogparser({
|
|
35
|
+
binaryPath: xclogparserPath,
|
|
36
|
+
derivedDataPath,
|
|
37
|
+
workspacePath,
|
|
38
|
+
outputDir: tempDir,
|
|
39
|
+
});
|
|
40
|
+
const data = XcactivitylogDataSchemaZ.parse(JSON.parse(await fs_extra_1.default.readFile(jsonOutputPath, 'utf8')));
|
|
41
|
+
logger.info(formatReport(data));
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
logger.debug({ err }, 'Failed to analyze build performance; continuing without a report');
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
if (tempDir) {
|
|
48
|
+
await (0, results_1.asyncResult)(fs_extra_1.default.rm(tempDir, { force: true, recursive: true }));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function downloadXclogparser(tempDir, version, logger, proxyBaseUrl) {
|
|
53
|
+
const zipName = getXclogparserZipName(version);
|
|
54
|
+
const zipPath = path_1.default.join(tempDir, zipName);
|
|
55
|
+
const directUrl = `${XCLOGPARSER_DOWNLOAD_URL}/${zipName}`;
|
|
56
|
+
const proxiedUrl = getProxiedDownloadUrl({ directUrl, proxyBaseUrl });
|
|
57
|
+
if (proxiedUrl) {
|
|
58
|
+
const proxiedDownloadResult = await (0, results_1.asyncResult)(downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl: proxiedUrl }));
|
|
59
|
+
if (!proxiedDownloadResult.ok) {
|
|
60
|
+
logger.debug({ err: proxiedDownloadResult.reason }, 'Failed to prepare xclogparser via the proxy path; falling back to the direct URL');
|
|
61
|
+
await cleanupXclogparserArtifacts({ tempDir, zipPath });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return proxiedDownloadResult.value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return await downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl: directUrl });
|
|
68
|
+
}
|
|
69
|
+
async function downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl, }) {
|
|
70
|
+
await (0, downloader_1.default)(sourceUrl, zipPath, { retry: 3, timeout: XCLOGPARSER_DOWNLOAD_TIMEOUT_MS });
|
|
71
|
+
return await unpackXclogparser({ tempDir, zipPath });
|
|
72
|
+
}
|
|
73
|
+
async function unpackXclogparser({ tempDir, zipPath, }) {
|
|
74
|
+
await (0, turtle_spawn_1.default)('unzip', ['-q', zipPath, '-d', tempDir], { stdio: 'pipe' });
|
|
75
|
+
const binaryPath = path_1.default.join(tempDir, 'xclogparser');
|
|
76
|
+
await fs_extra_1.default.chmod(binaryPath, 0o755);
|
|
77
|
+
return binaryPath;
|
|
78
|
+
}
|
|
79
|
+
async function cleanupXclogparserArtifacts({ tempDir, zipPath, }) {
|
|
80
|
+
await (0, results_1.asyncResult)(fs_extra_1.default.rm(zipPath, { force: true }));
|
|
81
|
+
await (0, results_1.asyncResult)(fs_extra_1.default.rm(path_1.default.join(tempDir, 'xclogparser'), { force: true }));
|
|
82
|
+
}
|
|
83
|
+
async function runXclogparser({ binaryPath, derivedDataPath, workspacePath, outputDir, }) {
|
|
84
|
+
const outputPath = path_1.default.join(outputDir, XCLOGPARSER_OUTPUT_FILENAME);
|
|
85
|
+
await (0, turtle_spawn_1.default)(binaryPath, [
|
|
86
|
+
'parse',
|
|
87
|
+
'--derived_data',
|
|
88
|
+
derivedDataPath,
|
|
89
|
+
'--workspace',
|
|
90
|
+
workspacePath,
|
|
91
|
+
'--reporter',
|
|
92
|
+
'json',
|
|
93
|
+
'--output',
|
|
94
|
+
outputPath,
|
|
95
|
+
], { stdio: 'pipe' });
|
|
96
|
+
return outputPath;
|
|
97
|
+
}
|
|
98
|
+
const XcactivitylogStepSchemaZ = zod_1.z.object({
|
|
99
|
+
title: zod_1.z.string().optional(),
|
|
100
|
+
detailStepType: zod_1.z.string().optional(),
|
|
101
|
+
signature: zod_1.z.string().optional(),
|
|
102
|
+
duration: zod_1.z.number().optional(),
|
|
103
|
+
startTimestamp: zod_1.z.number().optional(),
|
|
104
|
+
endTimestamp: zod_1.z.number().optional(),
|
|
105
|
+
get subSteps() {
|
|
106
|
+
return zod_1.z.array(XcactivitylogStepSchemaZ).optional();
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
const XcactivitylogDataSchemaZ = zod_1.z.object({
|
|
110
|
+
schema: zod_1.z.union([zod_1.z.string(), zod_1.z.object({ name: zod_1.z.string().optional() })]).optional(),
|
|
111
|
+
subSteps: zod_1.z.array(XcactivitylogStepSchemaZ).optional(),
|
|
112
|
+
});
|
|
113
|
+
const COMPILE_DETAIL_TYPES = new Set(['cCompilation', 'compileAssetsCatalog', 'compileStoryboard']);
|
|
114
|
+
const COMPILE_SIGNATURE_PREFIXES = ['SwiftCompile ', 'SwiftGeneratePch '];
|
|
115
|
+
function getXclogparserZipName(version) {
|
|
116
|
+
return `XCLogParser-macOS-x86-64-arm64-${version}.zip`;
|
|
117
|
+
}
|
|
118
|
+
function getProxiedDownloadUrl({ directUrl, proxyBaseUrl, }) {
|
|
119
|
+
if (!proxyBaseUrl) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const parsedUrl = new URL(directUrl);
|
|
123
|
+
return directUrl.replace(`${parsedUrl.protocol}//${parsedUrl.host}`, `${proxyBaseUrl}/${parsedUrl.host}`);
|
|
124
|
+
}
|
|
125
|
+
function isCompileStep(step) {
|
|
126
|
+
const detailStepType = step.detailStepType ?? '';
|
|
127
|
+
const signature = step.signature ?? '';
|
|
128
|
+
if (COMPILE_DETAIL_TYPES.has(detailStepType)) {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
return COMPILE_SIGNATURE_PREFIXES.some(prefix => signature.startsWith(prefix));
|
|
132
|
+
}
|
|
133
|
+
function collectTopLevelCompileSteps(step, results = []) {
|
|
134
|
+
for (const child of step.subSteps ?? []) {
|
|
135
|
+
if (isCompileStep(child)) {
|
|
136
|
+
results.push(child);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
collectTopLevelCompileSteps(child, results);
|
|
140
|
+
}
|
|
141
|
+
return results;
|
|
142
|
+
}
|
|
143
|
+
function intervalFromStep(step) {
|
|
144
|
+
if (typeof step.startTimestamp !== 'number' || typeof step.endTimestamp !== 'number') {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return { start: step.startTimestamp, end: step.endTimestamp };
|
|
148
|
+
}
|
|
149
|
+
function computeActiveWallTime(intervals) {
|
|
150
|
+
if (intervals.length === 0) {
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
const sorted = [...intervals].sort((a, b) => a.start - b.start);
|
|
154
|
+
let activeWallTime = 0;
|
|
155
|
+
let currentStart = sorted[0].start;
|
|
156
|
+
let currentEnd = sorted[0].end;
|
|
157
|
+
for (const interval of sorted.slice(1)) {
|
|
158
|
+
if (interval.start <= currentEnd) {
|
|
159
|
+
currentEnd = Math.max(currentEnd, interval.end);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
activeWallTime += currentEnd - currentStart;
|
|
163
|
+
currentStart = interval.start;
|
|
164
|
+
currentEnd = interval.end;
|
|
165
|
+
}
|
|
166
|
+
activeWallTime += currentEnd - currentStart;
|
|
167
|
+
return activeWallTime;
|
|
168
|
+
}
|
|
169
|
+
function buildTargetMetrics(data, { minTaskSeconds = 0.5 } = {}) {
|
|
170
|
+
const results = [];
|
|
171
|
+
for (const step of data.subSteps ?? []) {
|
|
172
|
+
const title = step.title ?? '';
|
|
173
|
+
if (!title.startsWith('Build target ')) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const moduleName = title.replace('Build target ', '');
|
|
177
|
+
const compileSteps = collectTopLevelCompileSteps(step);
|
|
178
|
+
const taskSeconds = compileSteps.reduce((sum, s) => sum + (s.duration ?? 0), 0);
|
|
179
|
+
if (taskSeconds < minTaskSeconds) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const intervals = compileSteps.map(intervalFromStep).filter((i) => i !== null);
|
|
183
|
+
const minStart = intervals.length > 0 ? Math.min(...intervals.map(i => i.start)) : 0;
|
|
184
|
+
const maxEnd = intervals.length > 0 ? Math.max(...intervals.map(i => i.end)) : 0;
|
|
185
|
+
const wallSpan = intervals.length > 0 ? maxEnd - minStart : 0;
|
|
186
|
+
const activeWallTime = computeActiveWallTime(intervals);
|
|
187
|
+
results.push({ moduleName, taskSeconds, wallSpan, activeWallTime });
|
|
188
|
+
}
|
|
189
|
+
results.sort((a, b) => {
|
|
190
|
+
if (b.taskSeconds !== a.taskSeconds) {
|
|
191
|
+
return b.taskSeconds - a.taskSeconds;
|
|
192
|
+
}
|
|
193
|
+
if (b.wallSpan !== a.wallSpan) {
|
|
194
|
+
return b.wallSpan - a.wallSpan;
|
|
195
|
+
}
|
|
196
|
+
return a.moduleName.localeCompare(b.moduleName);
|
|
197
|
+
});
|
|
198
|
+
const totalTaskSeconds = results.reduce((sum, r) => sum + r.taskSeconds, 0);
|
|
199
|
+
return { results, totalTaskSeconds };
|
|
200
|
+
}
|
|
201
|
+
function formatSeconds(value) {
|
|
202
|
+
return `${value.toFixed(1)}s`;
|
|
203
|
+
}
|
|
204
|
+
function formatReport(data) {
|
|
205
|
+
const { results, totalTaskSeconds } = buildTargetMetrics(data);
|
|
206
|
+
const nameWidth = Math.max(6, ...results.map(r => r.moduleName.length)) + 2;
|
|
207
|
+
const taskWidth = 10;
|
|
208
|
+
const pctWidth = 8;
|
|
209
|
+
const wallWidth = 10;
|
|
210
|
+
const barMaxWidth = 20;
|
|
211
|
+
const maxTaskSeconds = results[0]?.taskSeconds ?? 1;
|
|
212
|
+
const header = '┌─' +
|
|
213
|
+
'─'.repeat(nameWidth) +
|
|
214
|
+
'─┬────────────┬──────────┬────────────┬─' +
|
|
215
|
+
'─'.repeat(barMaxWidth) +
|
|
216
|
+
'─┐';
|
|
217
|
+
const divider = '├─' +
|
|
218
|
+
'─'.repeat(nameWidth) +
|
|
219
|
+
'─┼────────────┼──────────┼────────────┼─' +
|
|
220
|
+
'─'.repeat(barMaxWidth) +
|
|
221
|
+
'─┤';
|
|
222
|
+
const footer = '└─' +
|
|
223
|
+
'─'.repeat(nameWidth) +
|
|
224
|
+
'─┴────────────┴──────────┴────────────┴─' +
|
|
225
|
+
'─'.repeat(barMaxWidth) +
|
|
226
|
+
'─┘';
|
|
227
|
+
const lines = [];
|
|
228
|
+
lines.push('');
|
|
229
|
+
lines.push('Xcode Build — Compile Metrics by Module');
|
|
230
|
+
lines.push(`Schema: ${typeof data.schema === 'string' ? data.schema : (data.schema?.name ?? 'unknown')}`);
|
|
231
|
+
lines.push('% Task = share of total Compile Task Seconds');
|
|
232
|
+
lines.push('Wall = first compile start to last compile end');
|
|
233
|
+
lines.push('');
|
|
234
|
+
lines.push(header);
|
|
235
|
+
lines.push('│ ' +
|
|
236
|
+
'Module'.padEnd(nameWidth) +
|
|
237
|
+
' │ ' +
|
|
238
|
+
'Task'.padStart(taskWidth) +
|
|
239
|
+
' │ ' +
|
|
240
|
+
'% Task'.padStart(pctWidth) +
|
|
241
|
+
' │ ' +
|
|
242
|
+
'Wall'.padStart(wallWidth) +
|
|
243
|
+
' │ ' +
|
|
244
|
+
' '.repeat(barMaxWidth) +
|
|
245
|
+
' │');
|
|
246
|
+
lines.push(divider);
|
|
247
|
+
for (const result of results) {
|
|
248
|
+
const pct = totalTaskSeconds === 0 ? 0 : (result.taskSeconds / totalTaskSeconds) * 100;
|
|
249
|
+
const barLength = Math.round((result.taskSeconds / maxTaskSeconds) * barMaxWidth);
|
|
250
|
+
const bar = '█'.repeat(barLength) + '░'.repeat(barMaxWidth - barLength);
|
|
251
|
+
lines.push('│ ' +
|
|
252
|
+
result.moduleName.padEnd(nameWidth) +
|
|
253
|
+
' │ ' +
|
|
254
|
+
formatSeconds(result.taskSeconds).padStart(taskWidth) +
|
|
255
|
+
' │ ' +
|
|
256
|
+
`${pct.toFixed(1)}%`.padStart(pctWidth) +
|
|
257
|
+
' │ ' +
|
|
258
|
+
formatSeconds(result.wallSpan).padStart(wallWidth) +
|
|
259
|
+
' │ ' +
|
|
260
|
+
bar +
|
|
261
|
+
' │');
|
|
262
|
+
}
|
|
263
|
+
lines.push(divider);
|
|
264
|
+
lines.push('│ ' +
|
|
265
|
+
'TOTAL'.padEnd(nameWidth) +
|
|
266
|
+
' │ ' +
|
|
267
|
+
formatSeconds(totalTaskSeconds).padStart(taskWidth) +
|
|
268
|
+
' │ ' +
|
|
269
|
+
'100.0%'.padStart(pctWidth) +
|
|
270
|
+
' │ ' +
|
|
271
|
+
'n/a'.padStart(wallWidth) +
|
|
272
|
+
' │ ' +
|
|
273
|
+
' '.repeat(barMaxWidth) +
|
|
274
|
+
' │');
|
|
275
|
+
lines.push(footer);
|
|
276
|
+
lines.push('');
|
|
277
|
+
return lines.join('\n');
|
|
278
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const GymfileArchiveTemplate = "suppress_xcode_output(true)\nclean(<%- CLEAN %>)\n\nscheme(\"<%- SCHEME %>\")\n<% if (SCHEME_BUILD_CONFIGURATION) { %>\nconfiguration(\"<%- SCHEME_BUILD_CONFIGURATION %>\")\n<% } %>\n\nexport_options({\n method: \"<%- EXPORT_METHOD %>\",\n provisioningProfiles: {<% _.forEach(PROFILES, function(profile) { %>\n \"<%- profile.BUNDLE_ID %>\" => \"<%- profile.UUID %>\",<% }); %>\n }<% if (ICLOUD_CONTAINER_ENVIRONMENT) { %>,\n iCloudContainerEnvironment: \"<%- ICLOUD_CONTAINER_ENVIRONMENT %>\"\n<% } %>\n})\n\nexport_xcargs \"OTHER_CODE_SIGN_FLAGS=\\\"--keychain <%- KEYCHAIN_PATH %>\\\"\"\n\ndisable_xcpretty(true)\nbuildlog_path(\"<%- LOGS_DIRECTORY %>\")\n\noutput_directory(\"<%- OUTPUT_DIRECTORY %>\")\n";
|
|
1
|
+
export declare const GymfileArchiveTemplate = "suppress_xcode_output(true)\nclean(<%- CLEAN %>)\n\nscheme(\"<%- SCHEME %>\")\n<% if (SCHEME_BUILD_CONFIGURATION) { %>\nconfiguration(\"<%- SCHEME_BUILD_CONFIGURATION %>\")\n<% } %>\n\nexport_options({\n method: \"<%- EXPORT_METHOD %>\",\n provisioningProfiles: {<% _.forEach(PROFILES, function(profile) { %>\n \"<%- profile.BUNDLE_ID %>\" => \"<%- profile.UUID %>\",<% }); %>\n }<% if (ICLOUD_CONTAINER_ENVIRONMENT) { %>,\n iCloudContainerEnvironment: \"<%- ICLOUD_CONTAINER_ENVIRONMENT %>\"\n<% } %>\n})\n\nexport_xcargs \"OTHER_CODE_SIGN_FLAGS=\\\"--keychain <%- KEYCHAIN_PATH %>\\\"\"\n\ndisable_xcpretty(true)\nbuildlog_path(\"<%- LOGS_DIRECTORY %>\")\n\nderived_data_path(\"<%- DERIVED_DATA_PATH %>\")\nresult_bundle(true)\nresult_bundle_path(\"<%- RESULT_BUNDLE_PATH %>\")\n\noutput_directory(\"<%- OUTPUT_DIRECTORY %>\")\n";
|
|
@@ -23,5 +23,9 @@ export_xcargs "OTHER_CODE_SIGN_FLAGS=\\"--keychain <%- KEYCHAIN_PATH %>\\""
|
|
|
23
23
|
disable_xcpretty(true)
|
|
24
24
|
buildlog_path("<%- LOGS_DIRECTORY %>")
|
|
25
25
|
|
|
26
|
+
derived_data_path("<%- DERIVED_DATA_PATH %>")
|
|
27
|
+
result_bundle(true)
|
|
28
|
+
result_bundle_path("<%- RESULT_BUNDLE_PATH %>")
|
|
29
|
+
|
|
26
30
|
output_directory("<%- OUTPUT_DIRECTORY %>")
|
|
27
31
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const GymfileSimulatorTemplate = "suppress_xcode_output(true)\nclean(<%- CLEAN %>)\n\nscheme(\"<%- SCHEME %>\")\n<% if (SCHEME_BUILD_CONFIGURATION) { %>\nconfiguration(\"<%- SCHEME_BUILD_CONFIGURATION %>\")\n<% } %>\n\nderived_data_path(\"<%- DERIVED_DATA_PATH %>\")\nskip_package_ipa(true)\nskip_archive(true)\ndestination(\"<%- SCHEME_SIMULATOR_DESTINATION %>\")\n\ndisable_xcpretty(true)\nbuildlog_path(\"<%- LOGS_DIRECTORY %>\")\n";
|
|
1
|
+
export declare const GymfileSimulatorTemplate = "suppress_xcode_output(true)\nclean(<%- CLEAN %>)\n\nscheme(\"<%- SCHEME %>\")\n<% if (SCHEME_BUILD_CONFIGURATION) { %>\nconfiguration(\"<%- SCHEME_BUILD_CONFIGURATION %>\")\n<% } %>\n\nderived_data_path(\"<%- DERIVED_DATA_PATH %>\")\nskip_package_ipa(true)\nskip_archive(true)\ndestination(\"<%- SCHEME_SIMULATOR_DESTINATION %>\")\n\ndisable_xcpretty(true)\nbuildlog_path(\"<%- LOGS_DIRECTORY %>\")\n\nresult_bundle(true)\nresult_bundle_path(\"<%- RESULT_BUNDLE_PATH %>\")\n";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SpawnOptions, SpawnResult } from '@expo/turtle-spawn';
|
|
2
|
+
import { Env } from '@expo/eas-build-job';
|
|
3
|
+
export declare function resolveEasCommandPrefixAndEnvAsync(): Promise<{
|
|
4
|
+
cmd: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
extraEnv: Env;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function runEasCliCommand({ args, options, }: {
|
|
9
|
+
args: string[];
|
|
10
|
+
options: SpawnOptions;
|
|
11
|
+
}): Promise<SpawnResult>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveEasCommandPrefixAndEnvAsync = resolveEasCommandPrefixAndEnvAsync;
|
|
7
|
+
exports.runEasCliCommand = runEasCliCommand;
|
|
8
|
+
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
9
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
10
|
+
const packageManager_1 = require("./packageManager");
|
|
11
|
+
async function probeEasdAsync() {
|
|
12
|
+
try {
|
|
13
|
+
const result = await (0, turtle_spawn_1.default)('easd', ['--help'], {
|
|
14
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
15
|
+
});
|
|
16
|
+
return result.status === 0;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function resolveEasCommandPrefixAndEnvAsync() {
|
|
23
|
+
const npxArgsPrefix = (await (0, packageManager_1.isAtLeastNpm7Async)()) ? ['-y'] : [];
|
|
24
|
+
if (process.env.ENVIRONMENT === 'development') {
|
|
25
|
+
if (await probeEasdAsync()) {
|
|
26
|
+
return { cmd: 'easd', args: [], extraEnv: {} };
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
cmd: 'npx',
|
|
30
|
+
args: [...npxArgsPrefix, `eas-cli@${eas_build_job_1.EasCliNpmTags.STAGING}`],
|
|
31
|
+
extraEnv: {},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
else if (process.env.ENVIRONMENT === 'staging') {
|
|
35
|
+
return {
|
|
36
|
+
cmd: 'npx',
|
|
37
|
+
args: [...npxArgsPrefix, `eas-cli@${eas_build_job_1.EasCliNpmTags.STAGING}`],
|
|
38
|
+
extraEnv: { EXPO_STAGING: '1' },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return {
|
|
43
|
+
cmd: 'npx',
|
|
44
|
+
args: [...npxArgsPrefix, `eas-cli@${eas_build_job_1.EasCliNpmTags.PRODUCTION}`],
|
|
45
|
+
extraEnv: {},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function runEasCliCommand({ args, options, }) {
|
|
50
|
+
const { logger, ...spawnOptions } = options;
|
|
51
|
+
const { cmd, args: commandPrefixArgs, extraEnv } = await resolveEasCommandPrefixAndEnvAsync();
|
|
52
|
+
return await (0, turtle_spawn_1.default)(cmd, [...commandPrefixArgs, ...args], {
|
|
53
|
+
...spawnOptions,
|
|
54
|
+
logger,
|
|
55
|
+
env: { ...spawnOptions.env, ...extraEnv },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { type bunyan } from '@expo/logger';
|
|
2
|
+
import { type BuildStepEnv } from '@expo/steps';
|
|
2
3
|
export declare enum PackageManager {
|
|
3
4
|
YARN = "yarn",
|
|
4
5
|
NPM = "npm",
|
|
5
6
|
PNPM = "pnpm",
|
|
6
7
|
BUN = "bun"
|
|
7
8
|
}
|
|
8
|
-
export declare function resolvePackageManager(directory: string
|
|
9
|
+
export declare function resolvePackageManager(directory: string, { env }: {
|
|
10
|
+
env: BuildStepEnv;
|
|
11
|
+
}): PackageManager;
|
|
9
12
|
/**
|
|
10
13
|
* Get the version of a package from the dist-tags.
|
|
11
14
|
* Returns null if the version cannot be resolved.
|
|
@@ -43,6 +43,7 @@ exports.findPackagerRootDir = findPackagerRootDir;
|
|
|
43
43
|
exports.isAtLeastNpm7Async = isAtLeastNpm7Async;
|
|
44
44
|
exports.shouldUseFrozenLockfile = shouldUseFrozenLockfile;
|
|
45
45
|
exports.getPackageVersionFromPackageJson = getPackageVersionFromPackageJson;
|
|
46
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
46
47
|
const PackageManagerUtils = __importStar(require("@expo/package-manager"));
|
|
47
48
|
const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
|
|
48
49
|
const semver_1 = __importDefault(require("semver"));
|
|
@@ -54,7 +55,7 @@ var PackageManager;
|
|
|
54
55
|
PackageManager["PNPM"] = "pnpm";
|
|
55
56
|
PackageManager["BUN"] = "bun";
|
|
56
57
|
})(PackageManager || (exports.PackageManager = PackageManager = {}));
|
|
57
|
-
function resolvePackageManager(directory) {
|
|
58
|
+
function resolvePackageManager(directory, { env }) {
|
|
58
59
|
try {
|
|
59
60
|
const manager = PackageManagerUtils.resolvePackageManager(directory);
|
|
60
61
|
if (manager === 'npm') {
|
|
@@ -66,13 +67,21 @@ function resolvePackageManager(directory) {
|
|
|
66
67
|
else if (manager === 'bun') {
|
|
67
68
|
return PackageManager.BUN;
|
|
68
69
|
}
|
|
69
|
-
else {
|
|
70
|
+
else if (manager === 'yarn') {
|
|
70
71
|
return PackageManager.YARN;
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
|
-
catch {
|
|
74
|
-
|
|
74
|
+
catch { }
|
|
75
|
+
const fallback = env.EAS_FALLBACK_PACKAGE_MANAGER;
|
|
76
|
+
if (fallback) {
|
|
77
|
+
const parsed = zod_1.z.enum(PackageManager).safeParse(fallback);
|
|
78
|
+
if (parsed.success) {
|
|
79
|
+
return parsed.data;
|
|
80
|
+
}
|
|
81
|
+
const allowed = Object.values(PackageManager).join(', ');
|
|
82
|
+
throw new eas_build_job_1.errors.UserError('EAS_INVALID_FALLBACK_PACKAGE_MANAGER', `Invalid EAS_FALLBACK_PACKAGE_MANAGER value "${fallback}" (expected one of: ${allowed}).`);
|
|
75
83
|
}
|
|
84
|
+
return PackageManager.YARN;
|
|
76
85
|
}
|
|
77
86
|
/**
|
|
78
87
|
* Get the version of a package from the dist-tags.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.8.1",
|
|
4
4
|
"bugs": "https://github.com/expo/eas-cli/issues",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Expo <support@expo.io>",
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"@expo/config": "55.0.10",
|
|
39
39
|
"@expo/config-plugins": "55.0.7",
|
|
40
40
|
"@expo/downloader": "18.5.0",
|
|
41
|
-
"@expo/eas-build-job": "18.
|
|
41
|
+
"@expo/eas-build-job": "18.8.0",
|
|
42
42
|
"@expo/env": "^0.4.0",
|
|
43
43
|
"@expo/logger": "18.5.0",
|
|
44
44
|
"@expo/package-manager": "1.9.10",
|
|
45
45
|
"@expo/plist": "^0.2.0",
|
|
46
46
|
"@expo/results": "^1.0.0",
|
|
47
47
|
"@expo/spawn-async": "1.7.2",
|
|
48
|
-
"@expo/steps": "18.
|
|
48
|
+
"@expo/steps": "18.8.0",
|
|
49
49
|
"@expo/template-file": "18.5.0",
|
|
50
50
|
"@expo/turtle-spawn": "18.5.0",
|
|
51
51
|
"@expo/xcpretty": "^4.3.1",
|
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
"typescript": "^5.5.4",
|
|
99
99
|
"uuid": "^9.0.1"
|
|
100
100
|
},
|
|
101
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "714aec69c79af71e68b0212cb3e511f6ccef2ae0"
|
|
102
102
|
}
|