@expo/build-tools 18.4.0 → 18.6.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.
Files changed (46) hide show
  1. package/dist/builders/android.js +13 -1
  2. package/dist/builders/ios.js +1 -1
  3. package/dist/common/setup.js +4 -3
  4. package/dist/context.d.ts +1 -1
  5. package/dist/context.js +1 -1
  6. package/dist/ios/configure.js +4 -0
  7. package/dist/ios/credentials/provisioningProfile.d.ts +1 -0
  8. package/dist/ios/credentials/provisioningProfile.js +5 -0
  9. package/dist/steps/easFunctions.js +0 -2
  10. package/dist/steps/functionGroups/build.js +115 -34
  11. package/dist/steps/functionGroups/maestroTest.js +0 -3
  12. package/dist/steps/functions/calculateEASUpdateRuntimeVersion.js +2 -2
  13. package/dist/steps/functions/configureEASUpdateIfInstalled.js +2 -2
  14. package/dist/steps/functions/repack.js +20 -3
  15. package/dist/steps/functions/restoreBuildCache.d.ts +8 -0
  16. package/dist/steps/functions/restoreBuildCache.js +85 -0
  17. package/dist/steps/functions/saveBuildCache.d.ts +8 -0
  18. package/dist/steps/functions/saveBuildCache.js +57 -0
  19. package/dist/steps/functions/startAndroidEmulator.js +19 -0
  20. package/dist/steps/functions/uploadToAsc.d.ts +3 -0
  21. package/dist/steps/functions/uploadToAsc.js +24 -1
  22. package/dist/steps/utils/ios/AscApiClient.d.ts +1 -1
  23. package/dist/steps/utils/ios/AscApiUtils.d.ts +5 -0
  24. package/dist/steps/utils/ios/AscApiUtils.js +16 -13
  25. package/dist/steps/utils/ios/configure.js +4 -0
  26. package/dist/steps/utils/ios/credentials/provisioningProfile.d.ts +1 -0
  27. package/dist/steps/utils/ios/credentials/provisioningProfile.js +5 -0
  28. package/dist/utils/AndroidEmulatorUtils.d.ts +5 -0
  29. package/dist/utils/AndroidEmulatorUtils.js +17 -0
  30. package/dist/utils/appConfig.d.ts +4 -2
  31. package/dist/utils/appConfig.js +36 -5
  32. package/dist/utils/expoCli.d.ts +4 -0
  33. package/dist/utils/expoCli.js +37 -0
  34. package/dist/utils/expoUpdates.d.ts +1 -1
  35. package/dist/utils/expoUpdates.js +4 -4
  36. package/dist/utils/gradleCacheKey.d.ts +2 -0
  37. package/dist/utils/gradleCacheKey.js +56 -0
  38. package/dist/utils/packageManager.d.ts +10 -0
  39. package/dist/utils/packageManager.js +21 -0
  40. package/dist/utils/project.d.ts +2 -1
  41. package/dist/utils/project.js +29 -2
  42. package/package.json +14 -13
  43. package/dist/steps/functions/internalMaestroTest.d.ts +0 -9
  44. package/dist/steps/functions/internalMaestroTest.js +0 -534
  45. package/dist/utils/findMaestroPathsFlowsToExecuteAsync.d.ts +0 -8
  46. package/dist/utils/findMaestroPathsFlowsToExecuteAsync.js +0 -184
@@ -0,0 +1,37 @@
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.ExpoCLIModuleNotFoundError = void 0;
7
+ exports.expoCommandAsync = expoCommandAsync;
8
+ const resolve_from_1 = __importDefault(require("resolve-from"));
9
+ const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
10
+ class ExpoCLIModuleNotFoundError extends Error {
11
+ }
12
+ exports.ExpoCLIModuleNotFoundError = ExpoCLIModuleNotFoundError;
13
+ function resolveExpoCLI(projectRoot) {
14
+ try {
15
+ return (resolve_from_1.default.silent(projectRoot, 'expo/bin/cli') ?? (0, resolve_from_1.default)(projectRoot, 'expo/bin/cli.js'));
16
+ }
17
+ catch (e) {
18
+ if (e.code === 'MODULE_NOT_FOUND') {
19
+ throw new ExpoCLIModuleNotFoundError(`The \`expo\` package was not found.`);
20
+ }
21
+ throw e;
22
+ }
23
+ }
24
+ async function expoCommandAsync(projectDir, args, options) {
25
+ const expoCliPath = resolveExpoCLI(projectDir);
26
+ return (0, turtle_spawn_1.default)(expoCliPath, args, {
27
+ cwd: projectDir,
28
+ stdio: 'pipe',
29
+ ...options,
30
+ env: {
31
+ ...options.env,
32
+ // NOTE: If we're reading user configs, if a user has set this, it might cause excessive output
33
+ // that can stop the command from being readable
34
+ EXPO_DEBUG: '0',
35
+ },
36
+ });
37
+ }
@@ -27,5 +27,5 @@ export declare function resolveRuntimeVersionForExpoUpdatesIfConfiguredAsync({ c
27
27
  } | null>;
28
28
  export declare function getChannelAsync(ctx: BuildContext<Job>): Promise<string | null>;
29
29
  export declare function getRuntimeVersionAsync(ctx: BuildContext<Job>): Promise<string | null>;
30
- export declare function isEASUpdateConfigured(ctx: BuildContext<Job>): boolean;
30
+ export declare function isEASUpdateConfigured(ctx: BuildContext<Job>): Promise<boolean>;
31
31
  export {};
@@ -86,7 +86,7 @@ This would cause any updates published on the local machine to not be compatible
86
86
  await logDiffFingerprints({ resolvedRuntime, ctx });
87
87
  throw new Error('Runtime version calculated on local machine not equal to runtime version calculated during build.');
88
88
  }
89
- if (isEASUpdateConfigured(ctx)) {
89
+ if (await isEASUpdateConfigured(ctx)) {
90
90
  if (ctx.job.updates?.channel !== undefined) {
91
91
  await configureEASExpoUpdatesAsync(ctx);
92
92
  }
@@ -101,7 +101,7 @@ This would cause any updates published on the local machine to not be compatible
101
101
  // NO-OP: Development clients don't need to have a channel set
102
102
  }
103
103
  else {
104
- const easUpdateUrl = ctx.appConfig.updates?.url ?? null;
104
+ const easUpdateUrl = (await ctx.appConfig).updates?.url ?? null;
105
105
  const jobProfile = ctx.job.buildProfile ?? null;
106
106
  ctx.logger.warn(`This build has an invalid EAS Update configuration: update.url is set to "${easUpdateUrl}" in app config, but a channel is not specified${jobProfile ? '' : ` for the current build profile "${jobProfile}" in eas.json`}.`);
107
107
  ctx.logger.warn(`- No channel will be set and EAS Update will be disabled for the build.`);
@@ -156,8 +156,8 @@ async function getRuntimeVersionAsync(ctx) {
156
156
  throw new Error(`Platform is not supported.`);
157
157
  }
158
158
  }
159
- function isEASUpdateConfigured(ctx) {
160
- const rawUrl = ctx.appConfig.updates?.url;
159
+ async function isEASUpdateConfigured(ctx) {
160
+ const rawUrl = (await ctx.appConfig).updates?.url;
161
161
  if (!rawUrl) {
162
162
  return false;
163
163
  }
@@ -0,0 +1,2 @@
1
+ export declare const GRADLE_CACHE_KEY_PREFIX = "android-gradle-cache-";
2
+ export declare function generateGradleCacheKeyAsync(workingDirectory: string): Promise<string>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.GRADLE_CACHE_KEY_PREFIX = void 0;
40
+ exports.generateGradleCacheKeyAsync = generateGradleCacheKeyAsync;
41
+ const PackageManagerUtils = __importStar(require("@expo/package-manager"));
42
+ const steps_1 = require("@expo/steps");
43
+ const path_1 = __importDefault(require("path"));
44
+ const packageManager_1 = require("./packageManager");
45
+ exports.GRADLE_CACHE_KEY_PREFIX = 'android-gradle-cache-';
46
+ async function generateGradleCacheKeyAsync(workingDirectory) {
47
+ const packagerRunDir = (0, packageManager_1.findPackagerRootDir)(workingDirectory);
48
+ const manager = PackageManagerUtils.createForProject(packagerRunDir);
49
+ const lockPath = path_1.default.join(packagerRunDir, manager.lockFile);
50
+ try {
51
+ return `${exports.GRADLE_CACHE_KEY_PREFIX}${(0, steps_1.hashFiles)([lockPath])}`;
52
+ }
53
+ catch (err) {
54
+ throw new Error(`Failed to read lockfile for Gradle cache key generation: ${err instanceof Error ? err.message : err}`);
55
+ }
56
+ }
@@ -1,3 +1,4 @@
1
+ import { type bunyan } from '@expo/logger';
1
2
  export declare enum PackageManager {
2
3
  YARN = "yarn",
3
4
  NPM = "npm",
@@ -5,6 +6,15 @@ export declare enum PackageManager {
5
6
  BUN = "bun"
6
7
  }
7
8
  export declare function resolvePackageManager(directory: string): PackageManager;
9
+ /**
10
+ * Get the version of a package from the dist-tags.
11
+ * Returns null if the version cannot be resolved.
12
+ */
13
+ export declare function resolvePackageVersionAsync({ logger, packageName, distTag, }: {
14
+ logger: bunyan;
15
+ packageName: string;
16
+ distTag: string;
17
+ }): Promise<string | null>;
8
18
  export declare function findPackagerRootDir(currentDir: string): string;
9
19
  export declare function isAtLeastNpm7Async(): Promise<boolean>;
10
20
  export declare function shouldUseFrozenLockfile({ env, sdkVersion, reactNativeVersion, }: {
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.PackageManager = void 0;
40
40
  exports.resolvePackageManager = resolvePackageManager;
41
+ exports.resolvePackageVersionAsync = resolvePackageVersionAsync;
41
42
  exports.findPackagerRootDir = findPackagerRootDir;
42
43
  exports.isAtLeastNpm7Async = isAtLeastNpm7Async;
43
44
  exports.shouldUseFrozenLockfile = shouldUseFrozenLockfile;
@@ -73,6 +74,26 @@ function resolvePackageManager(directory) {
73
74
  return PackageManager.YARN;
74
75
  }
75
76
  }
77
+ /**
78
+ * Get the version of a package from the dist-tags.
79
+ * Returns null if the version cannot be resolved.
80
+ */
81
+ async function resolvePackageVersionAsync({ logger, packageName, distTag, }) {
82
+ try {
83
+ const { stdout } = await (0, turtle_spawn_1.default)('npm', ['view', packageName, 'dist-tags', '--json'], {
84
+ stdio: 'pipe',
85
+ });
86
+ const distTags = JSON.parse(stdout);
87
+ if (distTag in distTags) {
88
+ return distTags[distTag];
89
+ }
90
+ }
91
+ catch (e) {
92
+ const message = e instanceof Error ? e.message : String(e);
93
+ logger.warn(`Unable to resolve version for ${packageName}@${distTag}: ${message}`);
94
+ }
95
+ return null;
96
+ }
76
97
  function findPackagerRootDir(currentDir) {
77
98
  return PackageManagerUtils.resolveWorkspaceRoot(currentDir) ?? currentDir;
78
99
  }
@@ -1,7 +1,8 @@
1
1
  import { SpawnOptions, SpawnPromise, SpawnResult } from '@expo/turtle-spawn';
2
2
  import { PackageManager } from '../utils/packageManager';
3
3
  /**
4
- * check if .yarnrc.yml exists in the project dir or in the workspace root dir
4
+ * check if .yarnrc.yml exists in the project dir or in the workspace root dir,
5
+ * or if the `yarn.lock` file is classic one, not a modern one
5
6
  */
6
7
  export declare function isUsingModernYarnVersion(projectDir: string): Promise<boolean>;
7
8
  export declare function runExpoCliCommand({ packageManager, args, options, }: {
@@ -11,13 +11,40 @@ const turtle_spawn_1 = __importDefault(require("@expo/turtle-spawn"));
11
11
  const fs_extra_1 = __importDefault(require("fs-extra"));
12
12
  const path_1 = __importDefault(require("path"));
13
13
  const packageManager_1 = require("../utils/packageManager");
14
+ async function readFirstChars(filePath, chars) {
15
+ return new Promise((resolve, reject) => {
16
+ const chunks = [];
17
+ const stream = fs_extra_1.default.createReadStream(filePath, {
18
+ start: 0,
19
+ end: chars - 1,
20
+ });
21
+ stream.on('error', reject);
22
+ stream.on('data', chunk => {
23
+ chunks.push(chunk);
24
+ });
25
+ stream.on('end', () => {
26
+ resolve(Buffer.concat(chunks).toString('utf8'));
27
+ });
28
+ });
29
+ }
14
30
  /**
15
- * check if .yarnrc.yml exists in the project dir or in the workspace root dir
31
+ * check if .yarnrc.yml exists in the project dir or in the workspace root dir,
32
+ * or if the `yarn.lock` file is classic one, not a modern one
16
33
  */
17
34
  async function isUsingModernYarnVersion(projectDir) {
35
+ const rootDir = (0, packageManager_1.findPackagerRootDir)(projectDir);
18
36
  const yarnrcPath = path_1.default.join(projectDir, '.yarnrc.yml');
19
37
  const yarnrcRootPath = path_1.default.join((0, packageManager_1.findPackagerRootDir)(projectDir), '.yarnrc.yml');
20
- return (await fs_extra_1.default.pathExists(yarnrcPath)) || (await fs_extra_1.default.pathExists(yarnrcRootPath));
38
+ if ((await fs_extra_1.default.pathExists(yarnrcPath)) || (await fs_extra_1.default.pathExists(yarnrcRootPath))) {
39
+ return true;
40
+ }
41
+ const yarnlockPath = path_1.default.join(rootDir, 'yarn.lock');
42
+ if (!(await fs_extra_1.default.pathExists(yarnlockPath))) {
43
+ return false;
44
+ }
45
+ // The yarn.lock file is for Yarn Classic, not Modern, if it contains "# yarn lockfile v1"
46
+ const startOfLockfile = await readFirstChars(yarnlockPath, 100);
47
+ return !/yarn lockfile v1/i.test(startOfLockfile);
21
48
  }
22
49
  function runExpoCliCommand({ packageManager, args, options, }) {
23
50
  const argsWithExpo = ['expo', ...args];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/build-tools",
3
- "version": "18.4.0",
3
+ "version": "18.6.0",
4
4
  "bugs": "https://github.com/expo/eas-cli/issues",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Expo <support@expo.io>",
@@ -24,30 +24,30 @@
24
24
  "prebuild": "yarn gql",
25
25
  "build": "tsc",
26
26
  "typecheck": "tsc",
27
- "prepack": "rm -rf dist *.tsbuildinfo && yarn gql && tsc -p tsconfig.build.json",
27
+ "prepack": "rimraf dist \"*.tsbuildinfo\" && yarn gql && tsc -p tsconfig.build.json",
28
28
  "jest-unit": "jest --config jest/unit-config.ts",
29
29
  "jest-integration": "jest --config jest/integration-config.ts",
30
30
  "jest-unit-watch": "jest --config jest/unit-config.ts --watch",
31
31
  "jest-integration-watch": "jest --config jest/integration-config.ts --watch",
32
- "clean": "rm -rf node_modules dist coverage *.tsbuildinfo",
32
+ "clean": "rimraf node_modules dist coverage \"*.tsbuildinfo\"",
33
33
  "gql": "gql.tada generate-schema ${API_SERVER_URL:-https://api.expo.dev}/graphql --output ./schema.graphql && gql.tada generate-output",
34
34
  "gql:local": "API_SERVER_URL=http://api.expo.test yarn gql",
35
35
  "test": "yarn jest-unit"
36
36
  },
37
37
  "dependencies": {
38
- "@expo/config": "10.0.6",
39
- "@expo/config-plugins": "9.0.12",
40
- "@expo/downloader": "18.0.1",
41
- "@expo/eas-build-job": "18.4.0",
38
+ "@expo/config": "55.0.10",
39
+ "@expo/config-plugins": "55.0.7",
40
+ "@expo/downloader": "18.5.0",
41
+ "@expo/eas-build-job": "18.6.0",
42
42
  "@expo/env": "^0.4.0",
43
- "@expo/logger": "18.0.1",
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.4.0",
49
- "@expo/template-file": "18.0.1",
50
- "@expo/turtle-spawn": "18.0.1",
48
+ "@expo/steps": "18.6.0",
49
+ "@expo/template-file": "18.5.0",
50
+ "@expo/turtle-spawn": "18.5.0",
51
51
  "@expo/xcpretty": "^4.3.1",
52
52
  "@google-cloud/storage": "^7.11.2",
53
53
  "@urql/core": "^6.0.1",
@@ -75,7 +75,7 @@
75
75
  "zod": "^4.3.5"
76
76
  },
77
77
  "devDependencies": {
78
- "@expo/repack-app": "~0.2.5",
78
+ "@expo/repack-app": "~0.4.1",
79
79
  "@types/fs-extra": "^11.0.4",
80
80
  "@types/jest": "^29.5.12",
81
81
  "@types/lodash": "^4.17.4",
@@ -91,11 +91,12 @@
91
91
  "jest": "^29.7.0",
92
92
  "memfs": "^4.17.1",
93
93
  "nock": "13.4.0",
94
+ "rimraf": "3.0.2",
94
95
  "ts-jest": "^29.1.4",
95
96
  "ts-mockito": "^2.6.1",
96
97
  "tslib": "^2.6.3",
97
98
  "typescript": "^5.5.4",
98
99
  "uuid": "^9.0.1"
99
100
  },
100
- "gitHead": "4e202db843be2dca6450af4b45ee76b226a662ea"
101
+ "gitHead": "0fb6dfc334f0e496d701ff2afad0d15da9a83478"
101
102
  }
@@ -1,9 +0,0 @@
1
- import { BuildFunction } from '@expo/steps';
2
- import { CustomBuildContext } from '../../customBuildContext';
3
- export declare function createInternalEasMaestroTestFunction(ctx: CustomBuildContext): BuildFunction;
4
- export declare function getMaestroTestCommand(params: {
5
- flow_path: string;
6
- output_format: string | undefined;
7
- /** Unused if `output_format` is undefined */
8
- output_path: string;
9
- }): [command: string, ...args: string[]];