@expo/build-tools 24.0.0 → 24.2.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/common/git.d.ts +1 -0
- package/dist/common/projectSources.js +25 -17
- package/dist/generic.js +11 -1
- package/dist/steps/easFunctions.js +2 -0
- package/dist/steps/functions/startAgentDeviceRemoteSession.js +7 -3
- package/dist/steps/functions/startAppiumRemoteSession.js +7 -3
- package/dist/steps/functions/startArgentRemoteSession.js +7 -3
- package/dist/steps/functions/startLocalEgress.d.ts +10 -0
- package/dist/steps/functions/startLocalEgress.js +156 -0
- package/dist/steps/functions/startWebPreviewRemoteSession.js +10 -4
- package/dist/steps/utils/localEgress.d.ts +152 -0
- package/dist/steps/utils/localEgress.js +550 -0
- package/dist/steps/utils/localEgressSession.d.ts +9 -0
- package/dist/steps/utils/localEgressSession.js +40 -0
- package/dist/steps/utils/remoteDeviceRunSession.d.ts +5 -1
- package/dist/steps/utils/remoteDeviceRunSession.js +31 -4
- package/dist/steps/utils/serveSimMetricsRecorder.d.ts +4 -1
- package/dist/steps/utils/serveSimMetricsRecorder.js +14 -6
- package/package.json +4 -4
|
@@ -49,7 +49,9 @@ exports.spawnDetached = spawnDetached;
|
|
|
49
49
|
exports.metricsCorsOriginToServeSimArgs = metricsCorsOriginToServeSimArgs;
|
|
50
50
|
exports.createServeSimArgs = createServeSimArgs;
|
|
51
51
|
exports.createExpoDeviceHubArgs = createExpoDeviceHubArgs;
|
|
52
|
+
exports.findAvailablePortAsync = findAvailablePortAsync;
|
|
52
53
|
exports.waitForWebPreviewReadyAsync = waitForWebPreviewReadyAsync;
|
|
54
|
+
exports.readServeSimPreviewTokenAsync = readServeSimPreviewTokenAsync;
|
|
53
55
|
exports.startServeSimWithTunnelAsync = startServeSimWithTunnelAsync;
|
|
54
56
|
exports.startExpoDeviceHubWithTunnelAsync = startExpoDeviceHubWithTunnelAsync;
|
|
55
57
|
exports.startDeviceWebPreviewWithTunnelAsync = startDeviceWebPreviewWithTunnelAsync;
|
|
@@ -71,6 +73,7 @@ const promises_1 = require("node:timers/promises");
|
|
|
71
73
|
const sentry_1 = require("../../sentry");
|
|
72
74
|
const retry_1 = require("../../utils/retry");
|
|
73
75
|
const turtleFetch_1 = require("../../utils/turtleFetch");
|
|
76
|
+
const serveSimMetricsRecorder_1 = require("./serveSimMetricsRecorder");
|
|
74
77
|
const XCODE_DEVELOPER_DIR = '/Applications/Xcode.app/Contents/Developer';
|
|
75
78
|
const WEB_PREVIEW_HOST = '127.0.0.1';
|
|
76
79
|
const SERVE_SIM_PACKAGE_NAME = '@expo/serve-sim';
|
|
@@ -510,6 +513,7 @@ function createServeSimArgs({ port, turnArgs = [], metricsCorsArgs = [], package
|
|
|
510
513
|
String(port),
|
|
511
514
|
'--host',
|
|
512
515
|
WEB_PREVIEW_HOST,
|
|
516
|
+
'--require-token',
|
|
513
517
|
'--transport',
|
|
514
518
|
'webrtc',
|
|
515
519
|
'--webrtc-codec',
|
|
@@ -586,8 +590,8 @@ async function waitForWebPreviewReadyAsync({ previewServer, serverName, port, ti
|
|
|
586
590
|
retries: 0,
|
|
587
591
|
timeout: 2_000,
|
|
588
592
|
});
|
|
589
|
-
WebPreviewReadyResponseSchema.parse(await response.json());
|
|
590
|
-
return;
|
|
593
|
+
const ready = WebPreviewReadyResponseSchema.parse(await response.json());
|
|
594
|
+
return ready.device;
|
|
591
595
|
}
|
|
592
596
|
catch (error) {
|
|
593
597
|
lastError = error;
|
|
@@ -596,7 +600,7 @@ async function waitForWebPreviewReadyAsync({ previewServer, serverName, port, ti
|
|
|
596
600
|
}
|
|
597
601
|
throw new eas_build_job_1.SystemError(`Timed out waiting for ${serverName} readiness at ${readyUrl}${lastError instanceof Error ? `: ${lastError.message}` : ''}. Last output:\n${previewServer.getOutput() || '<empty>'}`);
|
|
598
602
|
}
|
|
599
|
-
async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, serverName, packageSpec, createArgs, }) {
|
|
603
|
+
async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, serverName, packageSpec, createArgs, readPreviewTokenAsync, }) {
|
|
600
604
|
const port = await findAvailablePortAsync();
|
|
601
605
|
logger.info(`Launching ${packageSpec} on ${WEB_PREVIEW_HOST}:${port}.`);
|
|
602
606
|
const turnArgs = await fetchWebPreviewTurnArgsAsync(ctx, { env, logger });
|
|
@@ -607,7 +611,13 @@ async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, ti
|
|
|
607
611
|
});
|
|
608
612
|
try {
|
|
609
613
|
logger.info(`Waiting for ${serverName} to become ready.`);
|
|
610
|
-
await waitForWebPreviewReadyAsync({
|
|
614
|
+
const device = await waitForWebPreviewReadyAsync({
|
|
615
|
+
previewServer,
|
|
616
|
+
serverName,
|
|
617
|
+
port,
|
|
618
|
+
timeoutMs,
|
|
619
|
+
});
|
|
620
|
+
const previewToken = await readPreviewTokenAsync?.(device);
|
|
611
621
|
const tunnel = await startNgrokTunnelAsync({
|
|
612
622
|
port,
|
|
613
623
|
subdomainPrefix: 'web-preview',
|
|
@@ -617,6 +627,7 @@ async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, ti
|
|
|
617
627
|
});
|
|
618
628
|
return {
|
|
619
629
|
previewUrl: tunnel.url,
|
|
630
|
+
previewToken,
|
|
620
631
|
stopAsync: async () => {
|
|
621
632
|
const results = await Promise.allSettled([tunnel.stopAsync(), previewServer.stopAsync()]);
|
|
622
633
|
for (const result of results) {
|
|
@@ -632,6 +643,10 @@ async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, ti
|
|
|
632
643
|
throw error;
|
|
633
644
|
}
|
|
634
645
|
}
|
|
646
|
+
async function readServeSimPreviewTokenAsync(udid, stateDir = serveSimMetricsRecorder_1.SERVE_SIM_STATE_DIR) {
|
|
647
|
+
const servers = await (0, serveSimMetricsRecorder_1.readServeSimServersAsync)(stateDir);
|
|
648
|
+
return servers.find(server => server.udid === udid)?.token;
|
|
649
|
+
}
|
|
635
650
|
async function startServeSimWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, packageVersion, }) {
|
|
636
651
|
const metricsCorsArgs = metricsCorsOriginToServeSimArgs(env);
|
|
637
652
|
return await startWebPreviewWithTunnelAsync(ctx, {
|
|
@@ -642,6 +657,18 @@ async function startServeSimWithTunnelAsync(ctx, { baseDomain, env, logger, time
|
|
|
642
657
|
serverName: 'serve-sim',
|
|
643
658
|
packageSpec: createServeSimPackageSpec(packageVersion),
|
|
644
659
|
createArgs: (port, turnArgs) => createServeSimArgs({ port, turnArgs, metricsCorsArgs, packageVersion }),
|
|
660
|
+
readPreviewTokenAsync: async (device) => {
|
|
661
|
+
const previewToken = await readServeSimPreviewTokenAsync(device);
|
|
662
|
+
if (!previewToken) {
|
|
663
|
+
// A serve-sim that does not know --require-token fails earlier, in the readiness check, so
|
|
664
|
+
// reaching here means it started and left no token in its state file.
|
|
665
|
+
throw new eas_build_job_1.SystemError(`serve-sim became ready but wrote no session token for device ${device}. The preview is ` +
|
|
666
|
+
'on a public tunnel and would be reachable without one, so the session cannot continue. ' +
|
|
667
|
+
'This usually means the state file was not written as expected; retry the session, and ' +
|
|
668
|
+
'report it if it repeats.');
|
|
669
|
+
}
|
|
670
|
+
return previewToken;
|
|
671
|
+
},
|
|
645
672
|
});
|
|
646
673
|
}
|
|
647
674
|
async function startExpoDeviceHubWithTunnelAsync(ctx, { runtimePlatform, baseDomain, env, logger, timeoutMs, packageVersion, }) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type bunyan } from '@expo/logger';
|
|
2
|
+
export declare const SERVE_SIM_STATE_DIR: string;
|
|
2
3
|
type ServeSimServer = {
|
|
3
4
|
udid: string;
|
|
4
5
|
url: string;
|
|
6
|
+
token?: string;
|
|
5
7
|
};
|
|
6
8
|
export declare namespace ServeSimMetricsRecorder {
|
|
7
9
|
function startAsync({ logger, stateDir, pollIntervalMs, }: {
|
|
@@ -18,8 +20,9 @@ export declare namespace ServeSimMetricsRecorder {
|
|
|
18
20
|
}[]>;
|
|
19
21
|
}
|
|
20
22
|
export declare function readServeSimServersAsync(stateDir: string): Promise<ServeSimServer[]>;
|
|
21
|
-
export declare function streamServeSimMetricsToFileAsync({ serveSimUrl, filePath, signal, logger, }: {
|
|
23
|
+
export declare function streamServeSimMetricsToFileAsync({ serveSimUrl, serveSimToken, filePath, signal, logger, }: {
|
|
22
24
|
serveSimUrl: string;
|
|
25
|
+
serveSimToken?: string;
|
|
23
26
|
filePath: string;
|
|
24
27
|
signal: AbortSignal;
|
|
25
28
|
logger: bunyan;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ServeSimMetricsRecorder = void 0;
|
|
6
|
+
exports.ServeSimMetricsRecorder = exports.SERVE_SIM_STATE_DIR = void 0;
|
|
7
7
|
exports.readServeSimServersAsync = readServeSimServersAsync;
|
|
8
8
|
exports.streamServeSimMetricsToFileAsync = streamServeSimMetricsToFileAsync;
|
|
9
9
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
@@ -18,11 +18,11 @@ const POLL_INTERVAL_MS = 2_000;
|
|
|
18
18
|
const MAX_CONSECUTIVE_STREAM_FAILURES_PER_DEVICE = 10;
|
|
19
19
|
const END_STREAM_TIMEOUT_MS = 2_000;
|
|
20
20
|
// serve-sim's own per-device registry while serving: `${tmpdir}/serve-sim/server-<udid>.json`.
|
|
21
|
-
|
|
21
|
+
exports.SERVE_SIM_STATE_DIR = node_path_1.default.join(node_os_1.default.tmpdir(), 'serve-sim');
|
|
22
22
|
let activeSession = null;
|
|
23
23
|
var ServeSimMetricsRecorder;
|
|
24
24
|
(function (ServeSimMetricsRecorder) {
|
|
25
|
-
async function startAsync({ logger, stateDir = SERVE_SIM_STATE_DIR, pollIntervalMs = POLL_INTERVAL_MS, }) {
|
|
25
|
+
async function startAsync({ logger, stateDir = exports.SERVE_SIM_STATE_DIR, pollIntervalMs = POLL_INTERVAL_MS, }) {
|
|
26
26
|
if (activeSession) {
|
|
27
27
|
logger.info('serve-sim metrics polling is already running.');
|
|
28
28
|
return;
|
|
@@ -101,6 +101,7 @@ async function pollServeSimMetricsAsync(session) {
|
|
|
101
101
|
logger.info(`Collecting serve-sim metrics for ${server.udid}.`);
|
|
102
102
|
const donePromise = streamServeSimMetricsToFileAsync({
|
|
103
103
|
serveSimUrl: server.url,
|
|
104
|
+
serveSimToken: server.token,
|
|
104
105
|
filePath,
|
|
105
106
|
signal: streamSignal,
|
|
106
107
|
logger,
|
|
@@ -140,7 +141,11 @@ async function readServeSimServersAsync(stateDir) {
|
|
|
140
141
|
try {
|
|
141
142
|
const state = JSON.parse(await (0, promises_1.readFile)(node_path_1.default.join(stateDir, entry), 'utf-8'));
|
|
142
143
|
if (typeof state.device === 'string' && typeof state.url === 'string') {
|
|
143
|
-
servers.push({
|
|
144
|
+
servers.push({
|
|
145
|
+
udid: state.device,
|
|
146
|
+
url: state.url,
|
|
147
|
+
...(typeof state.token === 'string' ? { token: state.token } : {}),
|
|
148
|
+
});
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
catch {
|
|
@@ -149,7 +154,7 @@ async function readServeSimServersAsync(stateDir) {
|
|
|
149
154
|
}
|
|
150
155
|
return servers;
|
|
151
156
|
}
|
|
152
|
-
async function streamServeSimMetricsToFileAsync({ serveSimUrl, filePath, signal, logger, }) {
|
|
157
|
+
async function streamServeSimMetricsToFileAsync({ serveSimUrl, serveSimToken, filePath, signal, logger, }) {
|
|
153
158
|
const file = (0, node_fs_1.createWriteStream)(filePath, { flags: 'a' });
|
|
154
159
|
file.on('error', err => {
|
|
155
160
|
logger.warn({ err }, `serve-sim metrics file write failed for ${filePath}.`);
|
|
@@ -157,7 +162,10 @@ async function streamServeSimMetricsToFileAsync({ serveSimUrl, filePath, signal,
|
|
|
157
162
|
let receivedData = false;
|
|
158
163
|
let metadata;
|
|
159
164
|
try {
|
|
160
|
-
const response = await (0, node_fetch_1.default)(new URL('/metrics', serveSimUrl).toString(), {
|
|
165
|
+
const response = await (0, node_fetch_1.default)(new URL('/metrics', serveSimUrl).toString(), {
|
|
166
|
+
signal,
|
|
167
|
+
...(serveSimToken ? { headers: { Authorization: `Bearer ${serveSimToken}` } } : {}),
|
|
168
|
+
});
|
|
161
169
|
if (!response.ok || !response.body) {
|
|
162
170
|
logger.warn(`serve-sim /metrics responded ${response.status} for ${serveSimUrl}.`);
|
|
163
171
|
return { receivedData, metadata };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.2.0",
|
|
4
4
|
"bugs": "https://github.com/expo/eas-cli/issues",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Expo <support@expo.io>",
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"@expo/config": "55.0.10",
|
|
41
41
|
"@expo/config-plugins": "55.0.7",
|
|
42
42
|
"@expo/downloader": "24.0.0",
|
|
43
|
-
"@expo/eas-build-job": "24.
|
|
43
|
+
"@expo/eas-build-job": "24.2.0",
|
|
44
44
|
"@expo/env": "^0.4.0",
|
|
45
45
|
"@expo/logger": "24.0.0",
|
|
46
46
|
"@expo/package-manager": "1.9.10",
|
|
47
47
|
"@expo/plist": "^0.3.5",
|
|
48
48
|
"@expo/results": "^1.0.0",
|
|
49
49
|
"@expo/spawn-async": "1.7.2",
|
|
50
|
-
"@expo/steps": "24.
|
|
50
|
+
"@expo/steps": "24.2.0",
|
|
51
51
|
"@expo/template-file": "24.0.0",
|
|
52
52
|
"@expo/turtle-spawn": "24.0.0",
|
|
53
53
|
"@expo/xcpretty": "^4.3.1",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"typescript": "^5.5.4",
|
|
103
103
|
"uuid": "^9.0.1"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "97553334d4275d9f18ec23b92e6c3ebe9593767e"
|
|
106
106
|
}
|