mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-15 03:38:08 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14c334d321 | ||
|
|
5115e6d5c5 | ||
|
|
0a6b06ddd8 |
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { BuildTrigger, Job, Metadata } from '@expo/eas-build-job';
|
||||
import { BuildPhase, BuildTrigger, Job, Metadata } from '@expo/eas-build-job';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { vol } from 'memfs';
|
||||
|
||||
@@ -116,4 +116,30 @@ describe('BuildContext', () => {
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it('should use a custom phase display name for logger metadata', async () => {
|
||||
const logger = createMockLogger();
|
||||
|
||||
const ctx = new BuildContext(
|
||||
{
|
||||
triggeredBy: BuildTrigger.EAS_CLI,
|
||||
} as Job,
|
||||
{
|
||||
env: {
|
||||
__API_SERVER_URL: 'http://api.expo.test',
|
||||
},
|
||||
workingdir: '/workingdir',
|
||||
logger,
|
||||
logBuffer: { getLogs: () => [], getPhaseLogs: () => [] },
|
||||
uploadArtifact: jest.fn(),
|
||||
}
|
||||
);
|
||||
(jest.spyOn(ctx as any, 'collectAndUpdateEnvVariablesAsync') as any).mockResolvedValue(
|
||||
undefined
|
||||
);
|
||||
|
||||
await ctx.runBuildPhase('Configure Android version', async () => undefined);
|
||||
|
||||
expect(logger.child).toHaveBeenCalledWith({ phase: 'Configure Android version' });
|
||||
});
|
||||
});
|
||||
@@ -12,6 +12,23 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe(resolveBuildPhaseErrorAsync, () => {
|
||||
it('omits non-enum buildPhase on the returned build error', async () => {
|
||||
const fakeError = new Error();
|
||||
const err = await resolveBuildPhaseErrorAsync(
|
||||
fakeError,
|
||||
['some log line'],
|
||||
{
|
||||
job: { platform: Platform.ANDROID } as Job,
|
||||
phase: 'Configure Android version',
|
||||
env: {},
|
||||
},
|
||||
'/fake/path'
|
||||
);
|
||||
|
||||
expect(err.errorCode).toBe(errors.ErrorCode.UNKNOWN_ERROR);
|
||||
expect(err.buildPhase).toBeUndefined();
|
||||
});
|
||||
|
||||
it('detects log for corrupted npm package', async () => {
|
||||
const fakeError = new Error();
|
||||
const err = await resolveBuildPhaseErrorAsync(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BuildPhase, errors } from '@expo/eas-build-job';
|
||||
import { BuildPhase, errors, isBuildPhase } from '@expo/eas-build-job';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import { buildErrorHandlers } from './buildErrorHandlers';
|
||||
@@ -7,7 +7,7 @@ import { userErrorHandlers } from './userErrorHandlers';
|
||||
import { findXcodeBuildLogsPathAsync } from '../ios/xcodeBuildLogs';
|
||||
|
||||
async function maybeReadXcodeBuildLogs(
|
||||
phase: BuildPhase,
|
||||
phase: BuildPhase | string | undefined,
|
||||
buildLogsDirectory: string
|
||||
): Promise<string | undefined> {
|
||||
if (phase !== BuildPhase.RUN_FASTLANE) {
|
||||
@@ -77,7 +77,7 @@ export async function resolveBuildPhaseErrorAsync(
|
||||
error instanceof errors.UserFacingError
|
||||
? error
|
||||
: (resolveError(userErrorHandlers, logLines, errorContext, xcodeBuildLogs) ??
|
||||
new errors.UnknownError(errorContext.phase));
|
||||
new errors.UnknownError(phase));
|
||||
const buildError = resolveError(buildErrorHandlers, logLines, errorContext, xcodeBuildLogs);
|
||||
|
||||
const trackingCode =
|
||||
@@ -90,7 +90,7 @@ export async function resolveBuildPhaseErrorAsync(
|
||||
trackingCode,
|
||||
docsUrl: userFacingError.docsUrl,
|
||||
cause: error,
|
||||
buildPhase: phase,
|
||||
...(phase && isBuildPhase(phase) ? { buildPhase: phase } : {}),
|
||||
metadata: buildError?.metadata,
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BuildMode, BuildPhase, Env, Job, Platform } from '@expo/eas-build-job';
|
||||
|
||||
export interface ErrorContext<TJob extends Job = Job> {
|
||||
phase: BuildPhase;
|
||||
phase: BuildPhase | string;
|
||||
job: TJob;
|
||||
env: Env;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
ManagedArtifactType,
|
||||
Metadata,
|
||||
errors,
|
||||
isBuildPhase,
|
||||
isGenericArtifact,
|
||||
} from '@expo/eas-build-job';
|
||||
import { BuildTrigger } from '@expo/eas-build-job/dist/common';
|
||||
@@ -91,7 +92,7 @@ export class BuildContext<TJob extends Job = Job> {
|
||||
private _metadata?: Metadata;
|
||||
private readonly defaultLogger: bunyan;
|
||||
private readonly _uploadArtifact: BuildContextOptions['uploadArtifact'];
|
||||
private buildPhase?: BuildPhase;
|
||||
private buildPhase?: BuildPhase | string;
|
||||
private buildPhaseSkipped = false;
|
||||
private buildPhaseHasWarnings = false;
|
||||
private _appConfig?: ExpoConfig;
|
||||
@@ -185,7 +186,7 @@ export class BuildContext<TJob extends Job = Job> {
|
||||
}
|
||||
|
||||
public async runBuildPhase<T>(
|
||||
buildPhase: BuildPhase,
|
||||
buildPhase: BuildPhase | string,
|
||||
phase: () => Promise<T>,
|
||||
{
|
||||
doNotMarkStart = false,
|
||||
@@ -283,7 +284,7 @@ export class BuildContext<TJob extends Job = Job> {
|
||||
|
||||
private async handleBuildPhaseErrorAsync(
|
||||
err: any,
|
||||
buildPhase: BuildPhase
|
||||
buildPhase: BuildPhase | string
|
||||
): Promise<errors.BuildError> {
|
||||
const buildError = await resolveBuildPhaseErrorAsync(
|
||||
err,
|
||||
@@ -316,7 +317,7 @@ export class BuildContext<TJob extends Job = Job> {
|
||||
return path.join(baseDirectory, this.job.projectRootDirectory ?? '.');
|
||||
}
|
||||
|
||||
private setBuildPhase(buildPhase: BuildPhase, { doNotMarkStart = false } = {}): void {
|
||||
private setBuildPhase(buildPhase: BuildPhase | string, { doNotMarkStart = false } = {}): void {
|
||||
if (this.buildPhase) {
|
||||
if (this.buildPhase === buildPhase) {
|
||||
return;
|
||||
@@ -349,7 +350,14 @@ export class BuildContext<TJob extends Job = Job> {
|
||||
}
|
||||
await this.collectAndUpdateEnvVariablesAsync();
|
||||
|
||||
this.reportBuildPhaseStats?.({ buildPhase: this.buildPhase, result, durationMs });
|
||||
const buildPhase = this.buildPhase;
|
||||
if (isBuildPhase(buildPhase)) {
|
||||
this.reportBuildPhaseStats?.({
|
||||
buildPhase,
|
||||
result,
|
||||
durationMs,
|
||||
});
|
||||
}
|
||||
|
||||
if (!doNotMarkEnd) {
|
||||
this.logger.info(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BuildPhase, buildPhaseDisplayName } from './logs';
|
||||
import { BuildPhase, buildPhaseDisplayName, isBuildPhase } from './logs';
|
||||
|
||||
export enum ErrorCode {
|
||||
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
||||
@@ -94,11 +94,11 @@ export class UserFacingError<
|
||||
}
|
||||
|
||||
export class UnknownError extends UserFacingError {
|
||||
constructor(buildPhase?: BuildPhase) {
|
||||
constructor(buildPhase?: BuildPhase | string) {
|
||||
super(
|
||||
ErrorCode.UNKNOWN_ERROR,
|
||||
buildPhase
|
||||
? `Unknown error. See logs of the ${buildPhaseDisplayName[buildPhase]} build phase for more information.`
|
||||
? `Unknown error. See logs of the ${isBuildPhase(buildPhase) ? buildPhaseDisplayName[buildPhase] : buildPhase} build phase for more information.`
|
||||
: 'Unknown error. See logs for more information.'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,12 @@ export enum BuildPhase {
|
||||
COMPLETE_JOB = 'COMPLETE_JOB',
|
||||
}
|
||||
|
||||
const buildPhaseValues = new Set<string>(Object.values(BuildPhase));
|
||||
|
||||
export function isBuildPhase(value: string): value is BuildPhase {
|
||||
return buildPhaseValues.has(value);
|
||||
}
|
||||
|
||||
export enum SubmissionPhase {
|
||||
SPIN_UP_SUBMISSION_WORKER = 'SPIN_UP_SUBMISSION_WORKER',
|
||||
SUBMIT_TO_PLAY_STORE = 'SUBMIT_TO_PLAY_STORE',
|
||||
|
||||
Reference in new issue
Block a user