Compare commits

...
Author SHA1 Message Date
Quinlan Jung a4ca87aa9f [eas-cli] create debug fingerprints 2025-01-05 12:30:55 -08:00
Bartosz Kaszubowski 5e5b55f9e4 [eas-cli] wording tweaks for messages (#2790) 2025-01-02 15:40:00 +01:00
Kadi Kraman a1d086ffc6 [eas-cli] parse request body for error only when needed (#2784)
* Parse error only when needed

* Add changelog

* Fix linting
2024-12-20 15:36:39 +00:00
Phil Pluckthun 2a96d04be3 [eas-cli] Update deploy/alias log output copy (#2780)
* Update product name

* Highlight `Project export` text

* Update export copy

* Update product name for alias

* Add changelog entry
2024-12-19 13:04:33 +00:00
Phil Pluckthun d126ee988a [eas-cli] Prevent eas-cli dependencies check from running repeatedly (#2781)
* Only check for dependencies once

* Add CHANGELOG entry

* Apply lints
2024-12-19 13:03:58 +00:00
17 changed files with 44 additions and 26 deletions

No files matched your search

+5
View File
@@ -11,9 +11,14 @@ This is the log of notable changes to EAS CLI and related packages.
### 🐛 Bug fixes
- Show `eas deploy` upload error messages. ([#2771](https://github.com/expo/eas-cli/pull/2771) by [@kadikraman](https://github.com/kadikraman))
- Prevent EAS CLI dependencies check from running repeatedly. ([#2781](https://github.com/expo/eas-cli/pull/2781) by [@kitten](https://github.com/kitten))
- Prevent optimistic request body parsing for `eas deploy`. ([#2784](https://github.com/expo/eas-cli/pull/2784) by [@kadikraman](https://github.com/kadikraman))
### 🧹 Chores
- Update log output for `worker` deploy and alias commands. ([#2780](https://github.com/expo/eas-cli/pull/2780) by [@kitten](https://github.com/kitten))
- Update various messages wording. ([#2790](https://github.com/expo/eas-cli/pull/2790) by [@simek](https://github.com/simek))
## [14.2.0](https://github.com/expo/eas-cli/releases/tag/v14.2.0) - 2024-12-13
### 🎉 New features
+4 -1
View File
@@ -672,7 +672,9 @@ async function computeAndMaybeUploadRuntimeAndFingerprintMetadataAsync<T extends
const runtimeAndFingerprintMetadata =
await computeAndMaybeUploadFingerprintFromExpoUpdatesAsync(ctx);
if (!runtimeAndFingerprintMetadata?.fingerprintHash) {
const fingerprint = await computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync(ctx);
const fingerprint = await computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync(ctx, {
debug: true,
});
return {
...runtimeAndFingerprintMetadata,
...fingerprint,
@@ -739,6 +741,7 @@ async function computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync<T extends
workflow: ctx.workflow,
platforms: [ctx.platform],
env: ctx.env,
debug,
});
if (!fingerprint) {
return {};
@@ -103,6 +103,8 @@ export async function findProjectRootAsync({
}
}
let ranEnsureEasCliIsNotInDependencies = false;
/**
* Determine the project root directory and ensure some constraints about the project setup
* like CLI version and dependencies.
@@ -113,6 +115,9 @@ export async function findProjectRootAsync({
export async function findProjectDirAndVerifyProjectSetupAsync(): Promise<string> {
const projectDir = await findProjectRootAsync();
await applyCliConfigAsync(projectDir);
await ensureEasCliIsNotInDependenciesAsync(projectDir);
if (!ranEnsureEasCliIsNotInDependencies) {
ranEnsureEasCliIsNotInDependencies = true;
await ensureEasCliIsNotInDependenciesAsync(projectDir);
}
return projectDir;
}
@@ -42,13 +42,13 @@ export async function loadServerSideEnvironmentVariablesAsync({
if (Object.keys(serverEnvVars).length > 0) {
Log.log(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS servers: ${Object.keys(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${Object.keys(
serverEnvVars
).join(', ')}.`
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS servers.`
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS.`
);
}
Log.newLine();
@@ -120,7 +120,7 @@ export default class BuildVersionSyncView extends EasCommand {
const workflow = await resolveWorkflowAsync(projectDir, profileInfo.platform, vcsClient);
if (!remoteVersions?.buildVersion) {
Log.warn(
`Skipping versions sync for ${platformDisplayName}. There are no versions configured on Expo servers, use "eas build:version:set" or run a build to initialize it.`
`Skipping versions sync for ${platformDisplayName}. There are no versions configured on EAS, use "eas build:version:set" or run a build to initialize it.`
);
continue;
}
@@ -147,10 +147,10 @@ export default class DeviceDelete extends EasCommand {
graphqlClient: ExpoGraphqlClient,
chosenDevice: AppleDevice | AppleDeviceQueryResult
): Promise<void> {
const removalSpinner = ora(`Removing Apple device on Expo`).start();
const removalSpinner = ora(`Removing Apple device on EAS`).start();
try {
await AppleDeviceMutation.deleteAppleDeviceAsync(graphqlClient, chosenDevice.id);
removalSpinner.succeed('Removed Apple device from Expo');
removalSpinner.succeed('Removed Apple device from EAS');
} catch (err) {
removalSpinner.fail();
throw err;
@@ -105,12 +105,12 @@ export default class DeviceRename extends EasCommand {
chosenDevice: AppleDevice | AppleDeviceQueryResult,
newDeviceName: string
): Promise<void> {
const removalSpinner = ora(`Renaming Apple device on Expo`).start();
const removalSpinner = ora(`Renaming Apple device on EAS`).start();
try {
await AppleDeviceMutation.updateAppleDeviceAsync(graphqlClient, chosenDevice.id, {
name: newDeviceName,
});
removalSpinner.succeed('Renamed Apple device on Expo');
removalSpinner.succeed('Renamed Apple device on EAS');
} catch (err) {
removalSpinner.fail();
throw err;
+1 -1
View File
@@ -170,7 +170,7 @@ export default class EnvExec extends EasCommand {
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS servers.`
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS.`
);
}
Log.newLine();
@@ -83,11 +83,12 @@ export default class FingerprintCompare extends EasCommand {
const workflows = await resolveWorkflowPerPlatformAsync(projectDir, vcsClient);
const buildPlatform = buildWithFingerprint.platform;
const workflow = workflows[appPlatformToPlatform(buildPlatform)];
const isDebug = true;
const projectFingerprint = await createFingerprintAsync(projectDir, {
workflow,
platforms: [appPlatformToString(buildPlatform)],
debug: true,
debug: isDebug,
env: undefined,
});
if (!projectFingerprint) {
@@ -73,7 +73,7 @@ export default class WorkerAlias extends EasCommand {
enableJsonOutput();
}
Log.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
Log.warn('EAS Hosting is still in beta and subject to changes.');
const {
getDynamicPrivateProjectConfigAsync,
@@ -114,7 +114,7 @@ export default class WorkerDeploy extends EasCommand {
enableJsonOutput();
}
Log.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
Log.warn('EAS Hosting is still in beta and subject to changes.');
const {
getDynamicPrivateProjectConfigAsync,
@@ -426,7 +426,7 @@ async function resolveExportedProjectAsync(
if (!exportDirStat?.isDirectory()) {
throw new Error(
`No "${flags.exportDir}/" folder found. Prepare your project for deployment with "npx expo export --platform web"`
`No "${flags.exportDir}/" folder found. Export your app with "npx expo export --platform web"`
);
}
@@ -451,7 +451,8 @@ function logExportedProjectInfo(
// Only show the timestamp for exports older than 1 minute
if (project.modifiedAt && Date.now() - project.modifiedAt.getTime() > 60_000) {
modifiedAgo = ` - exported ${formatTimeAgo(project.modifiedAt)}`;
Log.warn(`> Project export: ${project.type}${modifiedAgo}}`);
} else {
Log.log(chalk`{dim > Project export: ${project.type}}`);
}
Log.log(chalk`{dim > Project export: ${project.type}${modifiedAgo}}`);
}
@@ -48,7 +48,7 @@ async function collectDataAndRegisterDeviceAsync(
}
const { udid, deviceClass, name } = deviceData;
const spinner = ora(`Registering Apple device on Expo`).start();
const spinner = ora(`Registering Apple device on EAS`).start();
try {
await AppleDeviceMutation.createAppleDeviceAsync(
graphqlClient,
@@ -45,7 +45,7 @@ async function collectDataAndRegisterDeviceAsync(
): Promise<void> {
const { udid, deviceClass, name } = await collectDeviceDataAsync(appleTeam);
const spinner = ora(`Registering Apple device on Expo`).start();
const spinner = ora(`Registering Apple device on EAS`).start();
try {
await AppleDeviceMutation.createAppleDeviceAsync(
graphqlClient,
@@ -84,13 +84,13 @@ export async function fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsyn
const projectDashboardUrl = getProjectDashboardUrl(accountName, projectName);
const projectLink = link(projectDashboardUrl, { text: projectFullName });
const spinner = ora(`Creating ${chalk.bold(projectFullName)} on Expo`).start();
const spinner = ora(`Creating ${chalk.bold(projectFullName)} on EAS`).start();
try {
const id = await AppMutation.createAppAsync(graphqlClient, {
accountId: account.id,
projectName,
});
spinner.succeed(`Created ${chalk.bold(projectLink)} on Expo`);
spinner.succeed(`Created ${chalk.bold(projectLink)} on EAS`);
return id;
} catch (err) {
spinner.fail();
+1
View File
@@ -923,6 +923,7 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
workflow: workflowsByPlatform[platform],
projectDir,
env,
debug: true,
};
fingerprintOptionsByRuntimeAndPlatform.set(runtimeAndPlatform, options);
}
@@ -42,13 +42,13 @@ function warnAboutServiceOutage(service: StatuspageServiceFragment): void {
if (service.incidents.length > 0) {
const [currentIncident] = service.incidents;
Log.warn(`Reason: ${currentIncident.name}`);
Log.warn(`Reason: ${currentIncident.name}.`);
}
Log.warn(
`All information on service status and incidents available at ${link(
'https://status.expo.dev/'
)}.`
)}`
);
Log.newLine();
}
+6 -4
View File
@@ -109,8 +109,10 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
return retry(error);
}
const body = await response.json().catch(() => null);
const errorMessage = body?.error ?? `Upload of "${filePath}" failed: ${response.statusText}`;
const getErrorMessageAsync = async (): Promise<string> => {
const body = await response.json().catch(() => null);
return body?.error ?? `Upload of "${filePath}" failed: ${response.statusText}`;
};
if (
response.status === 408 ||
@@ -118,12 +120,12 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
response.status === 429 ||
(response.status >= 500 && response.status <= 599)
) {
return retry(new Error(errorMessage));
return retry(new Error(await getErrorMessageAsync()));
} else if (response.status === 413) {
const message = `Upload of "${filePath}" failed: File size exceeded the upload limit`;
throw new Error(message);
} else if (!response.ok) {
throw new Error(errorMessage);
throw new Error(await getErrorMessageAsync());
}
return {