From 2b59a5e2ee2ad1a7fcf405380f62f29ce4ba9baf Mon Sep 17 00:00:00 2001 From: Will Schurman Date: Wed, 6 Mar 2024 09:13:20 -0800 Subject: [PATCH] =?UTF-8?q?Revert=20"[eas-cli]=20Use=20expo-updates=20runt?= =?UTF-8?q?ime=20version=20CLI=20to=20generate=20runtime=20ve=E2=80=A6"=20?= =?UTF-8?q?(#2264)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 561e3bbb5ac2e5211d92a4f1f6a4c9bb8f807dc9. --- CHANGELOG.md | 1 - packages/eas-cli/src/build/metadata.ts | 6 ++- packages/eas-cli/src/project/publish.ts | 52 +++++++++---------- .../src/project/resolveRuntimeVersionAsync.ts | 44 ---------------- .../src/rollout/actions/CreateRollout.ts | 4 +- packages/eas-cli/src/utils/expoUpdatesCli.ts | 34 ++++++------ 6 files changed, 48 insertions(+), 93 deletions(-) delete mode 100644 packages/eas-cli/src/project/resolveRuntimeVersionAsync.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 14aafceb3e..b5f2e7d8a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,6 @@ This is the log of notable changes to EAS CLI and related packages. - Fix expo-updates package version detection for canaries. ([#2243](https://github.com/expo/eas-cli/pull/2243) by [@wschurman](https://github.com/wschurman)) - Add missing `config` property to `eas.json` schema. ([#2248](https://github.com/expo/eas-cli/pull/2248) by [@sjchmiela](https://github.com/sjchmiela)) -- Use expo-updates runtime version CLI to generate runtime versions. ([#2251](https://github.com/expo/eas-cli/pull/2251) by [@wschurman](https://github.com/wschurman)) ### 🧹 Chores diff --git a/packages/eas-cli/src/build/metadata.ts b/packages/eas-cli/src/build/metadata.ts index 34497ec1f4..4393ce2d1c 100644 --- a/packages/eas-cli/src/build/metadata.ts +++ b/packages/eas-cli/src/build/metadata.ts @@ -1,3 +1,4 @@ +import { Updates } from '@expo/config-plugins'; import { Metadata, Platform, sanitizeMetadata } from '@expo/eas-build-job'; import { IosEnterpriseProvisioning } from '@expo/eas-json'; import fs from 'fs-extra'; @@ -14,7 +15,6 @@ import { isClassicUpdatesSupportedAsync, isExpoUpdatesInstalled, } from '../project/projectUtils'; -import { resolveRuntimeVersionAsync } from '../project/resolveRuntimeVersionAsync'; import { readChannelSafelyAsync as readAndroidChannelSafelyAsync, readReleaseChannelSafelyAsync as readAndroidReleaseChannelSafelyAsync, @@ -37,7 +37,9 @@ export async function collectMetadataAsync( workflow: ctx.workflow, credentialsSource: ctx.buildProfile.credentialsSource, sdkVersion: ctx.exp.sdkVersion, - runtimeVersion: (await resolveRuntimeVersionAsync(ctx)) ?? undefined, + runtimeVersion: + (await Updates.getRuntimeVersionNullableAsync(ctx.projectDir, ctx.exp, ctx.platform)) ?? + undefined, reactNativeVersion: await getReactNativeVersionAsync(ctx.projectDir), ...channelOrReleaseChannel, distribution, diff --git a/packages/eas-cli/src/project/publish.ts b/packages/eas-cli/src/project/publish.ts index 71a652012f..4fee6853a8 100644 --- a/packages/eas-cli/src/project/publish.ts +++ b/packages/eas-cli/src/project/publish.ts @@ -31,11 +31,7 @@ import { shouldUseVersionedExpoCLI, shouldUseVersionedExpoCLIWithExplicitPlatforms, } from '../utils/expoCli'; -import { - ExpoUpdatesCLIInvalidCommandError, - ExpoUpdatesCLIModuleNotFoundError, - expoUpdatesCommandAsync, -} from '../utils/expoUpdatesCli'; +import { expoUpdatesCommandAsync } from '../utils/expoUpdatesCli'; import chunk from '../utils/expodash/chunk'; import { truthy } from '../utils/expodash/filter'; import uniqBy from '../utils/expodash/uniqBy'; @@ -721,31 +717,31 @@ async function getRuntimeVersionForPlatformAsync({ return 'UNVERSIONED'; } - try { - const resolvedRuntimeVersionJSONResult = await expoUpdatesCommandAsync(projectDir, [ - 'runtimeversion:resolve', - '--platform', - platform, - ]); - const runtimeVersionResult = JSON.parse(resolvedRuntimeVersionJSONResult); - if (runtimeVersionResult.fingerprintSources) { - Log.debug(`Resolved fingeprint runtime version for platform "${platform}". Sources:`); - Log.debug(runtimeVersionResult.fingerprintSources); - } - return nullthrows(runtimeVersionResult.runtimeVersion); - } catch (e: any) { - // if it's a known set of errors thrown by the CLI it means that we need to default back to the - // previous behavior, otherwise we throw the error since something is wrong - if ( - !(e instanceof ExpoUpdatesCLIModuleNotFoundError) && - !(e instanceof ExpoUpdatesCLIInvalidCommandError) - ) { - throw e; - } - } - const runtimeVersion = exp[platform]?.runtimeVersion ?? exp.runtimeVersion; if (typeof runtimeVersion === 'object') { + const policy = runtimeVersion.policy; + + if (policy === 'fingerprintExperimental') { + // log to inform the user that the fingerprint has been calculated + Log.warn( + `Calculating native fingerprint for platform ${platform} using current state of the "${platform}" directory. ` + + `If the fingerprint differs from the build's fingerint, ensure the state of your project is consistent ` + + `(repository is clean, ios and android native directories are in the same state as the build if applicable).` + ); + + const fingerprintRawString = await expoUpdatesCommandAsync(projectDir, [ + 'fingerprint:generate', + '--platform', + platform, + ]); + const fingerprintObject = JSON.parse(fingerprintRawString); + const hash = nullthrows( + fingerprintObject.hash, + 'invalid response from expo-update CLI for fingerprint generation' + ); + return hash; + } + const workflow = await resolveWorkflowAsync( projectDir, platform as EASBuildJobPlatform, diff --git a/packages/eas-cli/src/project/resolveRuntimeVersionAsync.ts b/packages/eas-cli/src/project/resolveRuntimeVersionAsync.ts deleted file mode 100644 index 0068a92c9b..0000000000 --- a/packages/eas-cli/src/project/resolveRuntimeVersionAsync.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ExpoConfig } from '@expo/config'; -import { Updates } from '@expo/config-plugins'; - -import Log from '../log'; -import { - ExpoUpdatesCLIInvalidCommandError, - ExpoUpdatesCLIModuleNotFoundError, - expoUpdatesCommandAsync, -} from '../utils/expoUpdatesCli'; - -export async function resolveRuntimeVersionAsync({ - exp, - platform, - projectDir, -}: { - exp: ExpoConfig; - platform: 'ios' | 'android'; - projectDir: string; -}): Promise { - try { - const resolvedRuntimeVersionJSONResult = await expoUpdatesCommandAsync(projectDir, [ - 'runtimeversion:resolve', - '--platform', - platform, - ]); - const runtimeVersionResult = JSON.parse(resolvedRuntimeVersionJSONResult); - if (runtimeVersionResult.fingerprintSources) { - Log.debug(`Resolved fingeprint runtime version for platform "${platform}". Sources:`); - Log.debug(runtimeVersionResult.fingerprintSources); - } - return runtimeVersionResult.runtimeVersion ?? null; - } catch (e: any) { - // if expo-updates is not installed, there's no need for a runtime version in the build - if (e instanceof ExpoUpdatesCLIModuleNotFoundError) { - return null; - } else if (e instanceof ExpoUpdatesCLIInvalidCommandError) { - // fall back to the previous behavior (using the @expo/config-plugins eas-cli dependency rather - // than the versioned @expo/config-plugins dependency in the project) - return await Updates.getRuntimeVersionNullableAsync(projectDir, exp, platform); - } - - throw e; - } -} diff --git a/packages/eas-cli/src/rollout/actions/CreateRollout.ts b/packages/eas-cli/src/rollout/actions/CreateRollout.ts index 85f56ba959..c104a988ef 100644 --- a/packages/eas-cli/src/rollout/actions/CreateRollout.ts +++ b/packages/eas-cli/src/rollout/actions/CreateRollout.ts @@ -1,3 +1,4 @@ +import { Updates } from '@expo/config-plugins'; import assert from 'assert'; import { SelectRuntime } from './SelectRuntime'; @@ -23,7 +24,6 @@ import { } from '../../graphql/queries/ChannelQuery'; import { UpdateQuery } from '../../graphql/queries/UpdateQuery'; import Log from '../../log'; -import { resolveRuntimeVersionAsync } from '../../project/resolveRuntimeVersionAsync'; import { confirmAsync, promptAsync } from '../../prompts'; import { truthy } from '../../utils/expodash/filter'; import { @@ -275,7 +275,7 @@ export class CreateRollout implements EASUpdateAction - resolveRuntimeVersionAsync({ projectDir: ctx.app.projectDir, exp: ctx.app.exp, platform }) + Updates.getRuntimeVersionAsync(ctx.app.projectDir, ctx.app.exp, platform) ) ) ).filter(truthy); diff --git a/packages/eas-cli/src/utils/expoUpdatesCli.ts b/packages/eas-cli/src/utils/expoUpdatesCli.ts index e50fed024f..0119d31df2 100644 --- a/packages/eas-cli/src/utils/expoUpdatesCli.ts +++ b/packages/eas-cli/src/utils/expoUpdatesCli.ts @@ -1,10 +1,8 @@ import spawnAsync from '@expo/spawn-async'; +import chalk from 'chalk'; import resolveFrom, { silent as silentResolveFrom } from 'resolve-from'; -import { link } from '../log'; - -export class ExpoUpdatesCLIModuleNotFoundError extends Error {} -export class ExpoUpdatesCLIInvalidCommandError extends Error {} +import Log, { link } from '../log'; export async function expoUpdatesCommandAsync(projectDir: string, args: string[]): Promise { let expoUpdatesCli; @@ -14,7 +12,7 @@ export async function expoUpdatesCommandAsync(projectDir: string, args: string[] resolveFrom(projectDir, 'expo-updates/bin/cli.js'); } catch (e: any) { if (e.code === 'MODULE_NOT_FOUND') { - throw new ExpoUpdatesCLIModuleNotFoundError( + throw new Error( `The \`expo-updates\` package was not found. Follow the installation directions at ${link( 'https://docs.expo.dev/bare/installing-expo-modules/' )}` @@ -23,16 +21,20 @@ export async function expoUpdatesCommandAsync(projectDir: string, args: string[] throw e; } - try { - return (await spawnAsync(expoUpdatesCli, args)).stdout; - } catch (e: any) { - if (e.stderr) { - if ((e.stderr as string).includes('Invalid command')) { - throw new ExpoUpdatesCLIInvalidCommandError( - `The command specified by ${args} was not valid in the \`expo-updates\` CLI.` - ); - } - } - throw e; + const spawnPromise = spawnAsync(expoUpdatesCli, args, { + stdio: ['inherit', 'pipe', 'pipe'], // inherit stdin so user can install a missing expo-cli from inside this command + }); + const { + child: { stderr }, + } = spawnPromise; + if (!stderr) { + throw new Error('Failed to spawn expo-updates cli'); } + stderr.on('data', data => { + for (const line of data.toString().trim().split('\n')) { + Log.warn(`${chalk.gray('[expo-cli]')} ${line}`); + } + }); + const result = await spawnPromise; + return result.stdout; }