@expo/build-tools 19.0.0 → 19.0.2

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.
@@ -10,8 +10,10 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
10
10
  const path_1 = __importDefault(require("path"));
11
11
  async function parseGradleProfile(androidDir) {
12
12
  const profileDir = path_1.default.join(androidDir, 'build', 'reports', 'profile');
13
+ // Gradle profile may not exist for all builds (e.g. custom, repack
14
+ // jobs). We should short circuit and not unnecessarily log.
13
15
  if (!(await fs_extra_1.default.pathExists(profileDir))) {
14
- throw new Error(`Gradle profile directory not found at ${profileDir}`);
16
+ return [];
15
17
  }
16
18
  const files = await fs_extra_1.default.readdir(profileDir);
17
19
  const htmlFile = files
@@ -20,6 +20,7 @@ const fastlane_1 = require("../ios/fastlane");
20
20
  const pod_1 = require("../ios/pod");
21
21
  const resign_1 = require("../ios/resign");
22
22
  const resolve_1 = require("../ios/resolve");
23
+ const sentry_1 = require("../sentry");
23
24
  const xcactivitylog_1 = require("../steps/utils/ios/xcactivitylog");
24
25
  const restoreBuildCache_1 = require("../steps/functions/restoreBuildCache");
25
26
  const saveBuildCache_1 = require("../steps/functions/saveBuildCache");
@@ -158,17 +159,26 @@ async function buildAsync(ctx) {
158
159
  await credentialsManager.cleanUp();
159
160
  });
160
161
  }
161
- if (ctx.env.EXPERIMENTAL_EAS_XCACTIVITYLOG === '1') {
162
- const { derivedDataPath, workspacePath } = (0, nullthrows_1.default)(fastlaneResult);
163
- await ctx.runBuildPhase(eas_build_job_1.BuildPhase.PARSE_XCACTIVITYLOG, async () => {
162
+ await ctx.runBuildPhase(eas_build_job_1.BuildPhase.PARSE_XCACTIVITYLOG, async () => {
163
+ if (ctx.isLocal) {
164
+ ctx.logger.info('Local builds skip build performance analysis.');
165
+ return;
166
+ }
167
+ try {
168
+ const { derivedDataPath, workspacePath } = (0, nullthrows_1.default)(fastlaneResult);
164
169
  await (0, xcactivitylog_1.parseAndReportXcactivitylog)({
165
170
  derivedDataPath,
166
171
  workspacePath,
167
172
  logger: ctx.logger,
168
173
  proxyBaseUrl: ctx.env.EAS_BUILD_COCOAPODS_CACHE_URL,
174
+ env: ctx.env,
169
175
  });
170
- });
171
- }
176
+ }
177
+ catch (err) {
178
+ sentry_1.Sentry.capture('Failed to parse xcactivitylog', err);
179
+ ctx.markBuildPhaseSkipped();
180
+ }
181
+ });
172
182
  await ctx.runBuildPhase(eas_build_job_1.BuildPhase.PRE_UPLOAD_ARTIFACTS_HOOK, async () => {
173
183
  await (0, hooks_1.runHookIfPresent)(ctx, hooks_1.Hook.PRE_UPLOAD_ARTIFACTS);
174
184
  });
@@ -43,6 +43,7 @@ function parseXcactivitylogFunction() {
43
43
  xclogparserVersion: version,
44
44
  logger: stepCtx.logger,
45
45
  proxyBaseUrl: env.EAS_BUILD_COCOAPODS_CACHE_URL,
46
+ env,
46
47
  });
47
48
  },
48
49
  });
@@ -1,16 +1,18 @@
1
1
  import { bunyan } from '@expo/logger';
2
+ import { BuildStepEnv } from '@expo/steps';
2
3
  import { z } from 'zod';
3
4
  /**
4
5
  * Never throws — best-effort observability that does not affect build status.
5
6
  * Failures route to Sentry via `Sentry.capture` for engineering triage;
6
7
  * users see only a generic skip message.
7
8
  */
8
- export declare function parseAndReportXcactivitylog({ derivedDataPath, workspacePath, xclogparserVersion, logger, proxyBaseUrl, }: {
9
+ export declare function parseAndReportXcactivitylog({ derivedDataPath, workspacePath, xclogparserVersion, logger, proxyBaseUrl, env, }: {
9
10
  derivedDataPath: string;
10
11
  workspacePath: string;
11
12
  xclogparserVersion?: string;
12
13
  logger: bunyan;
13
14
  proxyBaseUrl?: string;
15
+ env: BuildStepEnv;
14
16
  }): Promise<void>;
15
17
  declare const XcactivitylogStepSchemaZ: z.ZodObject<{
16
18
  title: z.ZodOptional<z.ZodString>;
@@ -25,19 +25,40 @@ const XCLOGPARSER_OUTPUT_FILENAME = 'xcactivitylog.json';
25
25
  * Failures route to Sentry via `Sentry.capture` for engineering triage;
26
26
  * users see only a generic skip message.
27
27
  */
28
- async function parseAndReportXcactivitylog({ derivedDataPath, workspacePath, xclogparserVersion = DEFAULT_XCLOGPARSER_VERSION, logger, proxyBaseUrl, }) {
28
+ async function parseAndReportXcactivitylog({ derivedDataPath, workspacePath, xclogparserVersion, logger, proxyBaseUrl, env, }) {
29
29
  let tempDir;
30
30
  let phase = 'creating_temp_directory';
31
31
  try {
32
32
  tempDir = await fs_extra_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'xclogparser-'));
33
- phase = 'downloading_xclogparser';
34
- const xclogparserPath = await downloadXclogparser(tempDir, xclogparserVersion, logger, proxyBaseUrl);
33
+ phase = 'resolving_xclogparser';
34
+ const preinstalledVersion = await detectPreinstalledXclogparserVersion(env);
35
+ let binaryPath;
36
+ let resolvedVersion;
37
+ if (preinstalledVersion &&
38
+ (!xclogparserVersion || preinstalledVersion === xclogparserVersion)) {
39
+ binaryPath = 'xclogparser';
40
+ resolvedVersion = preinstalledVersion;
41
+ logger.info(`Using preinstalled xclogparser ${resolvedVersion}.`);
42
+ }
43
+ else {
44
+ phase = 'downloading_xclogparser';
45
+ resolvedVersion = xclogparserVersion ?? DEFAULT_XCLOGPARSER_VERSION;
46
+ binaryPath = await downloadXclogparser({
47
+ tempDir,
48
+ version: resolvedVersion,
49
+ logger,
50
+ proxyBaseUrl,
51
+ env,
52
+ });
53
+ logger.info(`Using downloaded xclogparser ${resolvedVersion}.`);
54
+ }
35
55
  phase = 'running_xclogparser';
36
56
  const jsonOutputPath = await runXclogparser({
37
- binaryPath: xclogparserPath,
57
+ binaryPath,
38
58
  derivedDataPath,
39
59
  workspacePath,
40
60
  outputDir: tempDir,
61
+ env,
41
62
  });
42
63
  phase = 'parsing_xclogparser_output';
43
64
  const data = XcactivitylogDataSchemaZ.parse(JSON.parse(await fs_extra_1.default.readFile(jsonOutputPath, 'utf8')));
@@ -54,13 +75,21 @@ async function parseAndReportXcactivitylog({ derivedDataPath, workspacePath, xcl
54
75
  }
55
76
  }
56
77
  }
57
- async function downloadXclogparser(tempDir, version, logger, proxyBaseUrl) {
78
+ async function detectPreinstalledXclogparserVersion(env) {
79
+ const result = await (0, results_1.asyncResult)((0, turtle_spawn_1.default)('xclogparser', ['version'], { stdio: 'pipe', env }));
80
+ if (!result.ok) {
81
+ return null;
82
+ }
83
+ const match = result.value.stdout.match(/(\d+\.\d+\.\d+)/);
84
+ return match ? `v${match[1]}` : null;
85
+ }
86
+ async function downloadXclogparser({ tempDir, version, logger, proxyBaseUrl, env, }) {
58
87
  const zipName = getXclogparserZipName(version);
59
88
  const zipPath = path_1.default.join(tempDir, zipName);
60
89
  const directUrl = `${XCLOGPARSER_DOWNLOAD_URL}/${zipName}`;
61
90
  const proxiedUrl = getProxiedDownloadUrl({ directUrl, proxyBaseUrl });
62
91
  if (proxiedUrl) {
63
- const proxiedDownloadResult = await (0, results_1.asyncResult)(downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl: proxiedUrl }));
92
+ const proxiedDownloadResult = await (0, results_1.asyncResult)(downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl: proxiedUrl, env }));
64
93
  if (!proxiedDownloadResult.ok) {
65
94
  logger.debug({ err: proxiedDownloadResult.reason }, 'Failed to prepare xclogparser via the proxy path; falling back to the direct URL');
66
95
  await cleanupXclogparserArtifacts({ tempDir, zipPath });
@@ -69,14 +98,14 @@ async function downloadXclogparser(tempDir, version, logger, proxyBaseUrl) {
69
98
  return proxiedDownloadResult.value;
70
99
  }
71
100
  }
72
- return await downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl: directUrl });
101
+ return await downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl: directUrl, env });
73
102
  }
74
- async function downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl, }) {
103
+ async function downloadAndUnpackXclogparser({ tempDir, zipPath, sourceUrl, env, }) {
75
104
  await (0, downloader_1.default)(sourceUrl, zipPath, { retry: 3, timeout: XCLOGPARSER_DOWNLOAD_TIMEOUT_MS });
76
- return await unpackXclogparser({ tempDir, zipPath });
105
+ return await unpackXclogparser({ tempDir, zipPath, env });
77
106
  }
78
- async function unpackXclogparser({ tempDir, zipPath, }) {
79
- await (0, turtle_spawn_1.default)('unzip', ['-q', zipPath, '-d', tempDir], { stdio: 'pipe' });
107
+ async function unpackXclogparser({ tempDir, zipPath, env, }) {
108
+ await (0, turtle_spawn_1.default)('unzip', ['-q', zipPath, '-d', tempDir], { stdio: 'pipe', env });
80
109
  const binaryPath = path_1.default.join(tempDir, 'xclogparser');
81
110
  await fs_extra_1.default.chmod(binaryPath, 0o755);
82
111
  return binaryPath;
@@ -85,7 +114,7 @@ async function cleanupXclogparserArtifacts({ tempDir, zipPath, }) {
85
114
  await (0, results_1.asyncResult)(fs_extra_1.default.rm(zipPath, { force: true }));
86
115
  await (0, results_1.asyncResult)(fs_extra_1.default.rm(path_1.default.join(tempDir, 'xclogparser'), { force: true }));
87
116
  }
88
- async function runXclogparser({ binaryPath, derivedDataPath, workspacePath, outputDir, }) {
117
+ async function runXclogparser({ binaryPath, derivedDataPath, workspacePath, outputDir, env, }) {
89
118
  const outputPath = path_1.default.join(outputDir, XCLOGPARSER_OUTPUT_FILENAME);
90
119
  await (0, turtle_spawn_1.default)(binaryPath, [
91
120
  'parse',
@@ -95,9 +124,12 @@ async function runXclogparser({ binaryPath, derivedDataPath, workspacePath, outp
95
124
  workspacePath,
96
125
  '--reporter',
97
126
  'json',
127
+ '--omit_warnings',
128
+ '--omit_notes',
129
+ '--trunc_large_issues',
98
130
  '--output',
99
131
  outputPath,
100
- ], { stdio: 'pipe' });
132
+ ], { stdio: 'pipe', env });
101
133
  return outputPath;
102
134
  }
103
135
  const XcactivitylogStepSchemaZ = zod_1.z.object({
@@ -274,7 +306,7 @@ function formatReport(data) {
274
306
  ' │ ' +
275
307
  '100.0%'.padStart(pctWidth) +
276
308
  ' │ ' +
277
- 'n/a'.padStart(wallWidth) +
309
+ ' '.repeat(wallWidth) +
278
310
  ' │ ' +
279
311
  ' '.repeat(barMaxWidth) +
280
312
  ' │');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/build-tools",
3
- "version": "19.0.0",
3
+ "version": "19.0.2",
4
4
  "bugs": "https://github.com/expo/eas-cli/issues",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Expo <support@expo.io>",
@@ -99,5 +99,5 @@
99
99
  "typescript": "^5.5.4",
100
100
  "uuid": "^9.0.1"
101
101
  },
102
- "gitHead": "fc7c2950e773245d987c756b2bd2e8ba2ac6ee22"
102
+ "gitHead": "b64f25b36dd01aec10a03a503ab35e9f9fb5be41"
103
103
  }