@expo/build-tools 23.2.0 → 24.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/common/projectSources.js +4 -2
- package/dist/context.d.ts +2 -0
- package/dist/context.js +2 -0
- package/dist/customBuildContext.d.ts +1 -0
- package/dist/customBuildContext.js +2 -0
- 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/startAndroidEmulator.js +21 -0
- package/dist/steps/functions/startAppiumRemoteSession.js +7 -3
- package/dist/steps/functions/startArgentRemoteSession.js +26 -15
- 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/functions/uploadToAsc.js +11 -5
- package/dist/steps/utils/appiumCommandSummary.js +3 -0
- package/dist/steps/utils/appiumCommands.generated.d.ts +2 -2
- 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 +8 -18
- package/dist/steps/utils/remoteDeviceRunSession.js +66 -21
- package/dist/steps/utils/serveSimMetricsRecorder.d.ts +4 -1
- package/dist/steps/utils/serveSimMetricsRecorder.js +14 -6
- package/dist/utils/AndroidEmulatorUtils.d.ts +4 -1
- package/dist/utils/AndroidEmulatorUtils.js +5 -1
- package/dist/utils/logPhase.d.ts +2 -0
- package/dist/utils/logPhase.js +22 -0
- package/package.json +8 -8
|
@@ -41,7 +41,7 @@ exports.getNgrokTunnelDomainOrThrow = getNgrokTunnelDomainOrThrow;
|
|
|
41
41
|
exports.getNgrokAuthtokenOrThrow = getNgrokAuthtokenOrThrow;
|
|
42
42
|
exports.selectXcodeDeveloperDirectoryAsync = selectXcodeDeveloperDirectoryAsync;
|
|
43
43
|
exports.waitForDeviceRunSessionStoppedAsync = waitForDeviceRunSessionStoppedAsync;
|
|
44
|
-
exports.
|
|
44
|
+
exports.ensureFfmpegInstalledOnceAsync = ensureFfmpegInstalledOnceAsync;
|
|
45
45
|
exports.turnIceServersToWebPreviewArgs = turnIceServersToWebPreviewArgs;
|
|
46
46
|
exports.fetchWebPreviewTurnArgsAsync = fetchWebPreviewTurnArgsAsync;
|
|
47
47
|
exports.uploadRemoteSessionConfigAsync = uploadRemoteSessionConfigAsync;
|
|
@@ -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';
|
|
@@ -79,7 +82,7 @@ const SERVE_SIM_MJPEG_QUALITY = '0.55';
|
|
|
79
82
|
const SERVE_SIM_VIDEO_BITRATE = '6000000';
|
|
80
83
|
const SERVE_SIM_VIDEO_FPS = '60';
|
|
81
84
|
const EXPO_DEVICE_HUB_PACKAGE_NAME = 'expo-device-hub';
|
|
82
|
-
const EXPO_DEVICE_HUB_MAX_DIMENSION = '
|
|
85
|
+
const EXPO_DEVICE_HUB_MAX_DIMENSION = '960';
|
|
83
86
|
const EXPO_DEVICE_HUB_VIDEO_BITRATE = '6000000';
|
|
84
87
|
const EXPO_DEVICE_HUB_VIDEO_FPS = '60';
|
|
85
88
|
const START_DEVICE_RUN_SESSION_MUTATION = (0, gql_tada_1.graphql)(`
|
|
@@ -269,10 +272,9 @@ async function sleepUntilAbortedAsync(timeoutMs, signal) {
|
|
|
269
272
|
}
|
|
270
273
|
}
|
|
271
274
|
}
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
//
|
|
275
|
-
// with ENOENT when the binary is absent, and running it also proves it works.
|
|
275
|
+
// Device-session tools resolve `ffmpeg` from PATH. Spawning it with the step's
|
|
276
|
+
// environment rejects with ENOENT when the binary is absent, and running it also
|
|
277
|
+
// proves that the installed binary works.
|
|
276
278
|
async function isFfmpegAvailableAsync(env) {
|
|
277
279
|
return (await (0, results_1.asyncResult)((0, turtle_spawn_1.default)('ffmpeg', ['-version'], { env }))).ok;
|
|
278
280
|
}
|
|
@@ -290,14 +292,14 @@ async function installFfmpegWithAptAsync({ env, logger, }) {
|
|
|
290
292
|
await (0, results_1.asyncResult)((0, turtle_spawn_1.default)('sudo', ['apt-get', 'update'], { env: aptEnv, logger }));
|
|
291
293
|
await (0, turtle_spawn_1.default)('sudo', ['apt-get', 'install', '-y', 'ffmpeg'], { env: aptEnv, logger });
|
|
292
294
|
}
|
|
295
|
+
let ffmpegSetupPromise;
|
|
293
296
|
/**
|
|
294
|
-
* Install ffmpeg when the runtime does not already provide it
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
* on PATH" — on macOS (iOS simulators) and Linux (Android emulators) alike.
|
|
297
|
+
* Install ffmpeg when the runtime does not already provide it. Device-session
|
|
298
|
+
* tools use it for video encoding on macOS (iOS simulators) and Linux (Android
|
|
299
|
+
* emulators) alike, but the worker images do not ship it yet.
|
|
298
300
|
*
|
|
299
|
-
* Best-effort by design:
|
|
300
|
-
*
|
|
301
|
+
* Best-effort by design: a failure here is logged and the session continues
|
|
302
|
+
* without FFmpeg-dependent features.
|
|
301
303
|
*
|
|
302
304
|
* The whole body is wrapped because the caller runs this in the background with
|
|
303
305
|
* `void`. There is no unhandledRejection handler in the worker, so a rejection
|
|
@@ -312,7 +314,7 @@ async function ensureFfmpegInstalledAsync({ runtimePlatform, env, logger, }) {
|
|
|
312
314
|
return;
|
|
313
315
|
}
|
|
314
316
|
const isDarwin = runtimePlatform === steps_1.BuildRuntimePlatform.DARWIN;
|
|
315
|
-
logger.info(`ffmpeg is not installed, installing it with ${isDarwin ? 'Homebrew' : 'apt'} for
|
|
317
|
+
logger.info(`ffmpeg is not installed, installing it with ${isDarwin ? 'Homebrew' : 'apt'} for the device session.`);
|
|
316
318
|
if (isDarwin) {
|
|
317
319
|
await installFfmpegWithHomebrewAsync({ env, logger });
|
|
318
320
|
}
|
|
@@ -323,10 +325,26 @@ async function ensureFfmpegInstalledAsync({ runtimePlatform, env, logger, }) {
|
|
|
323
325
|
}
|
|
324
326
|
catch (err) {
|
|
325
327
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
326
|
-
sentry_1.Sentry.capture('Could not install ffmpeg for
|
|
328
|
+
sentry_1.Sentry.capture('Could not install ffmpeg for the device session', error, {
|
|
327
329
|
level: 'warning',
|
|
328
330
|
});
|
|
329
|
-
logger.warn({ err: error }, 'Could not install ffmpeg.
|
|
331
|
+
logger.warn({ err: error }, 'Could not install ffmpeg. FFmpeg-dependent features may not work in this session.');
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
async function ensureFfmpegInstalledOnceAsync({ runtimePlatform, env, logger, }) {
|
|
335
|
+
if (ffmpegSetupPromise) {
|
|
336
|
+
await ffmpegSetupPromise;
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const setupPromise = ensureFfmpegInstalledAsync({ runtimePlatform, env, logger });
|
|
340
|
+
ffmpegSetupPromise = setupPromise;
|
|
341
|
+
try {
|
|
342
|
+
await setupPromise;
|
|
343
|
+
}
|
|
344
|
+
finally {
|
|
345
|
+
if (ffmpegSetupPromise === setupPromise) {
|
|
346
|
+
ffmpegSetupPromise = undefined;
|
|
347
|
+
}
|
|
330
348
|
}
|
|
331
349
|
}
|
|
332
350
|
const TurnIceServersResponseSchema = zod_1.z.object({
|
|
@@ -495,6 +513,7 @@ function createServeSimArgs({ port, turnArgs = [], metricsCorsArgs = [], package
|
|
|
495
513
|
String(port),
|
|
496
514
|
'--host',
|
|
497
515
|
WEB_PREVIEW_HOST,
|
|
516
|
+
'--require-token',
|
|
498
517
|
'--transport',
|
|
499
518
|
'webrtc',
|
|
500
519
|
'--webrtc-codec',
|
|
@@ -571,8 +590,8 @@ async function waitForWebPreviewReadyAsync({ previewServer, serverName, port, ti
|
|
|
571
590
|
retries: 0,
|
|
572
591
|
timeout: 2_000,
|
|
573
592
|
});
|
|
574
|
-
WebPreviewReadyResponseSchema.parse(await response.json());
|
|
575
|
-
return;
|
|
593
|
+
const ready = WebPreviewReadyResponseSchema.parse(await response.json());
|
|
594
|
+
return ready.device;
|
|
576
595
|
}
|
|
577
596
|
catch (error) {
|
|
578
597
|
lastError = error;
|
|
@@ -581,7 +600,7 @@ async function waitForWebPreviewReadyAsync({ previewServer, serverName, port, ti
|
|
|
581
600
|
}
|
|
582
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>'}`);
|
|
583
602
|
}
|
|
584
|
-
async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, serverName, packageSpec, createArgs, }) {
|
|
603
|
+
async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, serverName, packageSpec, createArgs, readPreviewTokenAsync, }) {
|
|
585
604
|
const port = await findAvailablePortAsync();
|
|
586
605
|
logger.info(`Launching ${packageSpec} on ${WEB_PREVIEW_HOST}:${port}.`);
|
|
587
606
|
const turnArgs = await fetchWebPreviewTurnArgsAsync(ctx, { env, logger });
|
|
@@ -592,7 +611,13 @@ async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, ti
|
|
|
592
611
|
});
|
|
593
612
|
try {
|
|
594
613
|
logger.info(`Waiting for ${serverName} to become ready.`);
|
|
595
|
-
await waitForWebPreviewReadyAsync({
|
|
614
|
+
const device = await waitForWebPreviewReadyAsync({
|
|
615
|
+
previewServer,
|
|
616
|
+
serverName,
|
|
617
|
+
port,
|
|
618
|
+
timeoutMs,
|
|
619
|
+
});
|
|
620
|
+
const previewToken = await readPreviewTokenAsync?.(device);
|
|
596
621
|
const tunnel = await startNgrokTunnelAsync({
|
|
597
622
|
port,
|
|
598
623
|
subdomainPrefix: 'web-preview',
|
|
@@ -602,6 +627,7 @@ async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, ti
|
|
|
602
627
|
});
|
|
603
628
|
return {
|
|
604
629
|
previewUrl: tunnel.url,
|
|
630
|
+
previewToken,
|
|
605
631
|
stopAsync: async () => {
|
|
606
632
|
const results = await Promise.allSettled([tunnel.stopAsync(), previewServer.stopAsync()]);
|
|
607
633
|
for (const result of results) {
|
|
@@ -617,6 +643,10 @@ async function startWebPreviewWithTunnelAsync(ctx, { baseDomain, env, logger, ti
|
|
|
617
643
|
throw error;
|
|
618
644
|
}
|
|
619
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
|
+
}
|
|
620
650
|
async function startServeSimWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, packageVersion, }) {
|
|
621
651
|
const metricsCorsArgs = metricsCorsOriginToServeSimArgs(env);
|
|
622
652
|
return await startWebPreviewWithTunnelAsync(ctx, {
|
|
@@ -627,9 +657,24 @@ async function startServeSimWithTunnelAsync(ctx, { baseDomain, env, logger, time
|
|
|
627
657
|
serverName: 'serve-sim',
|
|
628
658
|
packageSpec: createServeSimPackageSpec(packageVersion),
|
|
629
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
|
+
},
|
|
630
672
|
});
|
|
631
673
|
}
|
|
632
|
-
async function startExpoDeviceHubWithTunnelAsync(ctx, { baseDomain, env, logger, timeoutMs, packageVersion, }) {
|
|
674
|
+
async function startExpoDeviceHubWithTunnelAsync(ctx, { runtimePlatform, baseDomain, env, logger, timeoutMs, packageVersion, }) {
|
|
675
|
+
if (runtimePlatform === steps_1.BuildRuntimePlatform.LINUX) {
|
|
676
|
+
await ensureFfmpegInstalledOnceAsync({ runtimePlatform, env, logger });
|
|
677
|
+
}
|
|
633
678
|
return await startWebPreviewWithTunnelAsync(ctx, {
|
|
634
679
|
baseDomain,
|
|
635
680
|
env,
|
|
@@ -645,7 +690,7 @@ async function startDeviceWebPreviewWithTunnelAsync(ctx, { runtimePlatform, ...o
|
|
|
645
690
|
case steps_1.BuildRuntimePlatform.DARWIN:
|
|
646
691
|
return await startServeSimWithTunnelAsync(ctx, options);
|
|
647
692
|
case steps_1.BuildRuntimePlatform.LINUX:
|
|
648
|
-
return await startExpoDeviceHubWithTunnelAsync(ctx, options);
|
|
693
|
+
return await startExpoDeviceHubWithTunnelAsync(ctx, { ...options, runtimePlatform });
|
|
649
694
|
}
|
|
650
695
|
}
|
|
651
696
|
async function startNgrokTunnelAsync({ port, subdomainPrefix, baseDomain, authtoken, rewriteHostHeader, logger, }) {
|
|
@@ -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 };
|
|
@@ -21,10 +21,13 @@ export declare namespace AndroidEmulatorUtils {
|
|
|
21
21
|
deviceName: AndroidVirtualDeviceName;
|
|
22
22
|
env: NodeJS.ProcessEnv;
|
|
23
23
|
}): Promise<AndroidDeviceSerialId | null>;
|
|
24
|
-
function createAsync({ deviceName, systemImagePackage, deviceIdentifier, env, logger, }: {
|
|
24
|
+
function createAsync({ deviceName, systemImagePackage, deviceIdentifier, lcdWidth, lcdHeight, lcdDensity, env, logger, }: {
|
|
25
25
|
deviceName: AndroidVirtualDeviceName;
|
|
26
26
|
systemImagePackage: string;
|
|
27
27
|
deviceIdentifier: AndroidDeviceName | null;
|
|
28
|
+
lcdWidth: number | null;
|
|
29
|
+
lcdHeight: number | null;
|
|
30
|
+
lcdDensity: number | null;
|
|
28
31
|
env: NodeJS.ProcessEnv;
|
|
29
32
|
logger: bunyan;
|
|
30
33
|
}): Promise<void>;
|
|
@@ -68,7 +68,7 @@ var AndroidEmulatorUtils;
|
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
70
70
|
AndroidEmulatorUtils.getSerialIdAsync = getSerialIdAsync;
|
|
71
|
-
async function createAsync({ deviceName, systemImagePackage, deviceIdentifier, env, logger, }) {
|
|
71
|
+
async function createAsync({ deviceName, systemImagePackage, deviceIdentifier, lcdWidth, lcdHeight, lcdDensity, env, logger, }) {
|
|
72
72
|
const avdManager = (0, turtle_spawn_1.default)('avdmanager', [
|
|
73
73
|
'create',
|
|
74
74
|
'avd',
|
|
@@ -121,6 +121,10 @@ var AndroidEmulatorUtils;
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
+
if (lcdWidth !== null && lcdHeight !== null && lcdDensity !== null) {
|
|
125
|
+
logger.info(`Setting screen resolution to ${lcdWidth}x${lcdHeight} and density to ${lcdDensity} ppi.`);
|
|
126
|
+
configIniFileContent = `${configIniFileContent}\nhw.lcd.height=${lcdHeight}\nhw.lcd.width=${lcdWidth}\nhw.lcd.density=${lcdDensity}\n`;
|
|
127
|
+
}
|
|
124
128
|
const shouldAdjustHeapSize = env.ANDROID_EMULATOR_ADJUST_HEAP_SIZE !== 'false' &&
|
|
125
129
|
env.ANDROID_EMULATOR_ADJUST_HEAP_SIZE !== '0';
|
|
126
130
|
if (shouldAdjustHeapSize) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withLogPhaseAsync = withLogPhaseAsync;
|
|
4
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
5
|
+
const steps_1 = require("@expo/steps");
|
|
6
|
+
async function withLogPhaseAsync(logger, name, fn) {
|
|
7
|
+
const phaseLogger = logger.child({
|
|
8
|
+
phase: eas_build_job_1.BuildPhase.CUSTOM,
|
|
9
|
+
buildStepId: steps_1.BuildStep.getNewId(),
|
|
10
|
+
buildStepDisplayName: name,
|
|
11
|
+
});
|
|
12
|
+
phaseLogger.info({ marker: eas_build_job_1.LogMarker.START_PHASE }, `Start phase: ${name}`);
|
|
13
|
+
try {
|
|
14
|
+
const result = await fn(phaseLogger);
|
|
15
|
+
phaseLogger.info({ marker: eas_build_job_1.LogMarker.END_PHASE, result: eas_build_job_1.BuildPhaseResult.SUCCESS }, `End phase: ${name}`);
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
phaseLogger.info({ marker: eas_build_job_1.LogMarker.END_PHASE, result: eas_build_job_1.BuildPhaseResult.FAIL }, `End phase: ${name}`);
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/build-tools",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "24.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>",
|
|
@@ -39,17 +39,17 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@expo/config": "55.0.10",
|
|
41
41
|
"@expo/config-plugins": "55.0.7",
|
|
42
|
-
"@expo/downloader": "
|
|
43
|
-
"@expo/eas-build-job": "
|
|
42
|
+
"@expo/downloader": "24.0.0",
|
|
43
|
+
"@expo/eas-build-job": "24.0.0",
|
|
44
44
|
"@expo/env": "^0.4.0",
|
|
45
|
-
"@expo/logger": "
|
|
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": "
|
|
51
|
-
"@expo/template-file": "
|
|
52
|
-
"@expo/turtle-spawn": "
|
|
50
|
+
"@expo/steps": "24.0.0",
|
|
51
|
+
"@expo/template-file": "24.0.0",
|
|
52
|
+
"@expo/turtle-spawn": "24.0.0",
|
|
53
53
|
"@expo/xcpretty": "^4.3.1",
|
|
54
54
|
"@ngrok/ngrok": "1.7.0",
|
|
55
55
|
"@sentry/node": "7.77.0",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"typescript": "^5.5.4",
|
|
103
103
|
"uuid": "^9.0.1"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "8373ae353ca615ba2170eac2399f7592ad72d36a"
|
|
106
106
|
}
|