@expo/build-tools 20.0.0 → 20.1.0
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/android.js +6 -0
- package/dist/builders/ios.js +6 -0
- package/dist/datadog.d.ts +8 -1
- package/dist/datadog.js +18 -12
- package/dist/steps/functions/startIosSimulator.js +12 -0
- package/dist/steps/utils/remoteDeviceRunSession.js +1 -1
- package/dist/utils/IosSimulatorUtils.d.ts +4 -0
- package/dist/utils/IosSimulatorUtils.js +5 -0
- package/dist/utils/expoUpdatesEmbedded.d.ts +3 -0
- package/dist/utils/expoUpdatesEmbedded.js +109 -0
- package/package.json +4 -4
package/dist/builders/android.js
CHANGED
|
@@ -22,6 +22,7 @@ const saveBuildCache_1 = require("../steps/functions/saveBuildCache");
|
|
|
22
22
|
const gradleConfig_1 = require("../steps/utils/android/gradleConfig");
|
|
23
23
|
const artifacts_1 = require("../utils/artifacts");
|
|
24
24
|
const expoUpdates_1 = require("../utils/expoUpdates");
|
|
25
|
+
const expoUpdatesEmbedded_1 = require("../utils/expoUpdatesEmbedded");
|
|
25
26
|
const hooks_1 = require("../utils/hooks");
|
|
26
27
|
const prepareBuildExecutable_1 = require("../utils/prepareBuildExecutable");
|
|
27
28
|
async function androidBuilder(ctx) {
|
|
@@ -177,6 +178,11 @@ async function buildAsync(ctx) {
|
|
|
177
178
|
logger: ctx.logger,
|
|
178
179
|
});
|
|
179
180
|
});
|
|
181
|
+
if (ctx.env.EAS_UPDATE_EXPERIMENTAL_UPLOAD_EMBEDDED_BUNDLE) {
|
|
182
|
+
await ctx.runBuildPhase(eas_build_job_1.BuildPhase.UPLOAD_EMBEDDED_BUNDLE, async () => {
|
|
183
|
+
await (0, expoUpdatesEmbedded_1.uploadEmbeddedBundleAsync)(ctx);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
180
186
|
await ctx.runBuildPhase(eas_build_job_1.BuildPhase.SAVE_CACHE, async () => {
|
|
181
187
|
if (ctx.isLocal) {
|
|
182
188
|
ctx.logger.info('Local builds do not support saving cache.');
|
package/dist/builders/ios.js
CHANGED
|
@@ -26,6 +26,7 @@ const restoreBuildCache_1 = require("../steps/functions/restoreBuildCache");
|
|
|
26
26
|
const saveBuildCache_1 = require("../steps/functions/saveBuildCache");
|
|
27
27
|
const artifacts_1 = require("../utils/artifacts");
|
|
28
28
|
const expoUpdates_1 = require("../utils/expoUpdates");
|
|
29
|
+
const expoUpdatesEmbedded_1 = require("../utils/expoUpdatesEmbedded");
|
|
29
30
|
const hooks_1 = require("../utils/hooks");
|
|
30
31
|
const prepareBuildExecutable_1 = require("../utils/prepareBuildExecutable");
|
|
31
32
|
const processes_1 = require("../utils/processes");
|
|
@@ -192,6 +193,11 @@ async function buildAsync(ctx) {
|
|
|
192
193
|
logger: ctx.logger,
|
|
193
194
|
});
|
|
194
195
|
});
|
|
196
|
+
if (ctx.env.EAS_UPDATE_EXPERIMENTAL_UPLOAD_EMBEDDED_BUNDLE) {
|
|
197
|
+
await ctx.runBuildPhase(eas_build_job_1.BuildPhase.UPLOAD_EMBEDDED_BUNDLE, async () => {
|
|
198
|
+
await (0, expoUpdatesEmbedded_1.uploadEmbeddedBundleAsync)(ctx);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
195
201
|
await ctx.runBuildPhase(eas_build_job_1.BuildPhase.SAVE_CACHE, async () => {
|
|
196
202
|
if (ctx.isLocal) {
|
|
197
203
|
ctx.logger.info('Local builds do not support saving cache.');
|
package/dist/datadog.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
type MetricsTarget = {
|
|
2
|
+
kind: 'build';
|
|
3
|
+
turtleBuildId: string;
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'jobRun';
|
|
6
|
+
turtleJobRunId: string;
|
|
7
|
+
};
|
|
1
8
|
type DatadogSetupOptions = {
|
|
2
9
|
expoApiV2BaseUrl: string;
|
|
3
|
-
turtleBuildId: string;
|
|
4
10
|
robotAccessToken: string;
|
|
11
|
+
target: MetricsTarget;
|
|
5
12
|
};
|
|
6
13
|
export declare const Datadog: {
|
|
7
14
|
setup(opts: DatadogSetupOptions | null): void;
|
package/dist/datadog.js
CHANGED
|
@@ -13,7 +13,7 @@ exports.Datadog = {
|
|
|
13
13
|
if (!setupOptions) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
-
const { expoApiV2BaseUrl,
|
|
16
|
+
const { expoApiV2BaseUrl, robotAccessToken, target } = setupOptions;
|
|
17
17
|
const metrics = [
|
|
18
18
|
{
|
|
19
19
|
name,
|
|
@@ -22,14 +22,17 @@ exports.Datadog = {
|
|
|
22
22
|
tags,
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
|
-
const
|
|
25
|
+
const metricsPath = target.kind === 'build'
|
|
26
|
+
? `turtle-builds/${target.turtleBuildId}/metrics`
|
|
27
|
+
: `turtle-job-runs/${target.turtleJobRunId}/metrics`;
|
|
28
|
+
const uploadPromise = (0, turtleFetch_1.turtleFetch)(new URL(metricsPath, expoApiV2BaseUrl).toString(), 'POST', {
|
|
26
29
|
json: { metrics },
|
|
27
30
|
headers: {
|
|
28
31
|
Authorization: `Bearer ${robotAccessToken}`,
|
|
29
32
|
},
|
|
30
33
|
retries: 2,
|
|
31
34
|
}).catch(err => {
|
|
32
|
-
sentry_1.Sentry.capture(
|
|
35
|
+
sentry_1.Sentry.capture(`Failed to report turtle ${target.kind} metric`, err, {
|
|
33
36
|
extras: { metrics },
|
|
34
37
|
});
|
|
35
38
|
});
|
|
@@ -39,26 +42,29 @@ exports.Datadog = {
|
|
|
39
42
|
if (!setupOptions) {
|
|
40
43
|
return;
|
|
41
44
|
}
|
|
42
|
-
const { expoApiV2BaseUrl,
|
|
43
|
-
const log =
|
|
44
|
-
buildId: turtleBuildId,
|
|
45
|
-
message,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const uploadPromise = (0, turtleFetch_1.turtleFetch)(new URL('turtle-builds/logs', expoApiV2BaseUrl).toString(), 'POST', {
|
|
45
|
+
const { expoApiV2BaseUrl, robotAccessToken, target } = setupOptions;
|
|
46
|
+
const log = target.kind === 'build'
|
|
47
|
+
? { buildId: target.turtleBuildId, message, tags }
|
|
48
|
+
: { jobRunId: target.turtleJobRunId, message, tags };
|
|
49
|
+
const logsPath = target.kind === 'build' ? 'turtle-builds/logs' : 'turtle-job-runs/logs';
|
|
50
|
+
const uploadPromise = (0, turtleFetch_1.turtleFetch)(new URL(logsPath, expoApiV2BaseUrl).toString(), 'POST', {
|
|
49
51
|
json: log,
|
|
50
52
|
headers: {
|
|
51
53
|
Authorization: `Bearer ${robotAccessToken}`,
|
|
52
54
|
},
|
|
53
55
|
shouldThrowOnNotOk: false,
|
|
54
56
|
}).catch(err => {
|
|
55
|
-
sentry_1.Sentry.capture(
|
|
57
|
+
sentry_1.Sentry.capture(`Failed to report turtle ${target.kind} log`, err, {
|
|
56
58
|
extras: { log },
|
|
57
59
|
});
|
|
58
60
|
});
|
|
59
61
|
pendingUploads.push(uploadPromise);
|
|
60
62
|
},
|
|
61
63
|
async flushAsync() {
|
|
62
|
-
|
|
64
|
+
// Rotate so each flush only awaits its own batch; uploads enqueued during the
|
|
65
|
+
// await land in the fresh array for a later flush.
|
|
66
|
+
const uploads = pendingUploads;
|
|
67
|
+
pendingUploads = [];
|
|
68
|
+
await Promise.allSettled(uploads);
|
|
63
69
|
},
|
|
64
70
|
};
|
|
@@ -52,6 +52,12 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
52
52
|
deviceIdentifier: originalDeviceIdentifier,
|
|
53
53
|
env,
|
|
54
54
|
});
|
|
55
|
+
try {
|
|
56
|
+
await IosSimulatorUtils_1.IosSimulatorUtils.disableApsdAsync({ udid, env });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
logger.warn({ err }, 'Failed to disable apsd in the Simulator.');
|
|
60
|
+
}
|
|
55
61
|
await IosSimulatorUtils_1.IosSimulatorUtils.waitForReadyAsync({ udid, env });
|
|
56
62
|
logger.info('');
|
|
57
63
|
const device = await IosSimulatorUtils_1.IosSimulatorUtils.getDeviceAsync({ udid, env });
|
|
@@ -76,6 +82,12 @@ function createStartIosSimulatorBuildFunction() {
|
|
|
76
82
|
deviceIdentifier: cloneDeviceName,
|
|
77
83
|
env,
|
|
78
84
|
});
|
|
85
|
+
try {
|
|
86
|
+
await IosSimulatorUtils_1.IosSimulatorUtils.disableApsdAsync({ udid: cloneUdid, env });
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
logger.warn({ err }, 'Failed to disable apsd in the Simulator.');
|
|
90
|
+
}
|
|
79
91
|
await IosSimulatorUtils_1.IosSimulatorUtils.waitForReadyAsync({
|
|
80
92
|
udid: cloneUdid,
|
|
81
93
|
env,
|
|
@@ -49,6 +49,10 @@ export declare namespace IosSimulatorUtils {
|
|
|
49
49
|
udid: IosSimulatorUuid;
|
|
50
50
|
env: NodeJS.ProcessEnv;
|
|
51
51
|
}): Promise<void>;
|
|
52
|
+
export function disableApsdAsync({ udid, env, }: {
|
|
53
|
+
udid: IosSimulatorUuid;
|
|
54
|
+
env: NodeJS.ProcessEnv;
|
|
55
|
+
}): Promise<void>;
|
|
52
56
|
export function collectLogsAsync({ deviceIdentifier, env, }: {
|
|
53
57
|
deviceIdentifier: IosSimulatorName | IosSimulatorUuid;
|
|
54
58
|
env: NodeJS.ProcessEnv;
|
|
@@ -77,6 +77,11 @@ var IosSimulatorUtils;
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
IosSimulatorUtils.waitForReadyAsync = waitForReadyAsync;
|
|
80
|
+
async function disableApsdAsync({ udid, env, }) {
|
|
81
|
+
await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'spawn', udid, 'launchctl', 'disable', 'system/com.apple.apsd'], { env });
|
|
82
|
+
await (0, turtle_spawn_1.default)('xcrun', ['simctl', 'spawn', udid, 'launchctl', 'bootout', 'system/com.apple.apsd'], { env });
|
|
83
|
+
}
|
|
84
|
+
IosSimulatorUtils.disableApsdAsync = disableApsdAsync;
|
|
80
85
|
async function collectLogsAsync({ deviceIdentifier, env, }) {
|
|
81
86
|
const outputDir = await node_fs_1.default.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'ios-simulator-logs-'));
|
|
82
87
|
const outputPath = node_path_1.default.join(outputDir, `${deviceIdentifier}.logarchive`);
|
|
@@ -0,0 +1,109 @@
|
|
|
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.uploadEmbeddedBundleAsync = uploadEmbeddedBundleAsync;
|
|
7
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
8
|
+
const logger_1 = require("@expo/logger");
|
|
9
|
+
const results_1 = require("@expo/results");
|
|
10
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
+
const os_1 = __importDefault(require("os"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const node_stream_zip_1 = __importDefault(require("node-stream-zip"));
|
|
14
|
+
const artifacts_1 = require("./artifacts");
|
|
15
|
+
const easCli_1 = require("./easCli");
|
|
16
|
+
const resolve_1 = require("../ios/resolve");
|
|
17
|
+
const expoUpdates_1 = require("./expoUpdates");
|
|
18
|
+
async function uploadEmbeddedBundleAsync(ctx) {
|
|
19
|
+
if (!(await (0, expoUpdates_1.isEASUpdateConfigured)(ctx))) {
|
|
20
|
+
ctx.markBuildPhaseSkipped();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { platform } = ctx.job;
|
|
24
|
+
if (platform === eas_build_job_1.Platform.IOS && ctx.job.simulator) {
|
|
25
|
+
ctx.markBuildPhaseSkipped();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const channel = ctx.job.updates?.channel;
|
|
29
|
+
if (!channel) {
|
|
30
|
+
ctx.logger.warn('Skipping embedded bundle upload: no channel configured for this build profile.');
|
|
31
|
+
ctx.markBuildPhaseHasWarnings();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const projectDir = ctx.getReactNativeProjectDirectory();
|
|
35
|
+
let archivePattern;
|
|
36
|
+
if (platform === eas_build_job_1.Platform.IOS) {
|
|
37
|
+
archivePattern = (0, resolve_1.resolveArtifactPath)(ctx);
|
|
38
|
+
}
|
|
39
|
+
else if (platform === eas_build_job_1.Platform.ANDROID) {
|
|
40
|
+
archivePattern =
|
|
41
|
+
ctx.job.applicationArchivePath ??
|
|
42
|
+
'android/app/build/outputs/**/*.{apk,aab}';
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new Error(`Uploading embedded updates is not supported for the ${platform} platform.`);
|
|
46
|
+
}
|
|
47
|
+
const [archivePath] = await (0, artifacts_1.findArtifacts)({
|
|
48
|
+
rootDir: projectDir,
|
|
49
|
+
patternOrPath: archivePattern,
|
|
50
|
+
logger: null,
|
|
51
|
+
}).catch(() => []);
|
|
52
|
+
if (!archivePath) {
|
|
53
|
+
ctx.logger.warn('Skipping embedded bundle upload: build archive not found.');
|
|
54
|
+
ctx.markBuildPhaseHasWarnings();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const tmpDir = await fs_extra_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'eas-embedded-bundle-'));
|
|
58
|
+
const bundleName = platform === eas_build_job_1.Platform.IOS ? 'main.jsbundle' : 'index.android.bundle';
|
|
59
|
+
const bundlePath = path_1.default.join(tmpDir, bundleName);
|
|
60
|
+
const manifestPath = path_1.default.join(tmpDir, 'app.manifest');
|
|
61
|
+
const zip = new node_stream_zip_1.default.async({ file: archivePath });
|
|
62
|
+
try {
|
|
63
|
+
const entries = Object.values(await zip.entries());
|
|
64
|
+
const bundleEntry = entries.find(e => platform === eas_build_job_1.Platform.IOS
|
|
65
|
+
? e.name.endsWith('/main.jsbundle')
|
|
66
|
+
: e.name.endsWith('assets/index.android.bundle'));
|
|
67
|
+
const manifestEntry = entries.find(e => platform === eas_build_job_1.Platform.IOS
|
|
68
|
+
? e.name.includes('EXUpdates.bundle/app.manifest')
|
|
69
|
+
: e.name.endsWith('assets/app.manifest'));
|
|
70
|
+
if (!bundleEntry || !manifestEntry) {
|
|
71
|
+
ctx.logger.warn('Skipping embedded bundle upload: bundle or manifest not found in archive.');
|
|
72
|
+
ctx.markBuildPhaseHasWarnings();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
await zip.extract(bundleEntry.name, bundlePath);
|
|
76
|
+
await zip.extract(manifestEntry.name, manifestPath);
|
|
77
|
+
const args = [
|
|
78
|
+
'update:embedded:upload',
|
|
79
|
+
'--platform',
|
|
80
|
+
platform,
|
|
81
|
+
'--bundle',
|
|
82
|
+
bundlePath,
|
|
83
|
+
'--manifest',
|
|
84
|
+
manifestPath,
|
|
85
|
+
'--channel',
|
|
86
|
+
channel,
|
|
87
|
+
'--non-interactive',
|
|
88
|
+
];
|
|
89
|
+
if (ctx.env.EAS_BUILD_ID) {
|
|
90
|
+
args.push('--build-id', ctx.env.EAS_BUILD_ID);
|
|
91
|
+
}
|
|
92
|
+
await (0, easCli_1.runEasCliCommand)({
|
|
93
|
+
args,
|
|
94
|
+
options: {
|
|
95
|
+
cwd: projectDir,
|
|
96
|
+
env: ctx.env,
|
|
97
|
+
logger: ctx.logger,
|
|
98
|
+
mode: logger_1.PipeMode.STDERR_ONLY_AS_STDOUT,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
ctx.logger.warn({ err }, 'Failed to upload embedded bundle.');
|
|
104
|
+
ctx.markBuildPhaseHasWarnings();
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
await (0, results_1.asyncResult)(zip.close());
|
|
108
|
+
}
|
|
109
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.1.0",
|
|
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": "20.0.0",
|
|
41
|
-
"@expo/eas-build-job": "20.
|
|
41
|
+
"@expo/eas-build-job": "20.1.0",
|
|
42
42
|
"@expo/env": "^0.4.0",
|
|
43
43
|
"@expo/logger": "20.0.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": "20.
|
|
48
|
+
"@expo/steps": "20.1.0",
|
|
49
49
|
"@expo/template-file": "20.0.0",
|
|
50
50
|
"@expo/turtle-spawn": "20.0.0",
|
|
51
51
|
"@expo/xcpretty": "^4.3.1",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"typescript": "^5.5.4",
|
|
101
101
|
"uuid": "^9.0.1"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "33225d2b73a34db5cbdfeaa537aedb6c6b4a84af"
|
|
104
104
|
}
|