Skip to content

Commit

Permalink
[local-build-plugin][build-tools][eas-build-job] copy Xcode build log…
Browse files Browse the repository at this point in the history
…s to target destination on local iOS build failure to simplify debuging
  • Loading branch information
szdziedzic committed Oct 14, 2024
1 parent 8a18c32 commit 73b604c
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 14 deletions.
5 changes: 4 additions & 1 deletion packages/build-tools/src/builders/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export async function runBuilderWithHooksAsync<T extends BuildJob>(
});
});

if (ctx.job.platform === Platform.IOS) {
if (
ctx.job.platform === Platform.IOS &&
(!buildSuccess || (buildSuccess && ctx.shouldUploadXcodeBuildLogsOnSuccess))
) {
await findAndUploadXcodeBuildLogsAsync(ctx as BuildContext<Ios.Job>, {
logger: ctx.logger,
});
Expand Down
3 changes: 3 additions & 0 deletions packages/build-tools/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export interface BuildContextOptions {
reportBuildPhaseStats?: (stats: BuildPhaseStats) => void;
skipNativeBuild?: boolean;
metadata?: Metadata;
shouldUploadXcodeBuildLogsOnSuccess?: boolean;
}

export class SkipNativeBuildError extends Error {}
Expand All @@ -77,6 +78,7 @@ export class BuildContext<TJob extends Job = Job> {
options?: { tags?: Record<string, string>; extras?: Record<string, string> }
) => void;
public readonly skipNativeBuild?: boolean;
public readonly shouldUploadXcodeBuildLogsOnSuccess: boolean;
public artifacts: Artifacts = {};

private _env: Env;
Expand All @@ -98,6 +100,7 @@ export class BuildContext<TJob extends Job = Job> {
this.cacheManager = options.cacheManager;
this._uploadArtifact = options.uploadArtifact;
this.reportError = options.reportError;
this.shouldUploadXcodeBuildLogsOnSuccess = options.shouldUploadXcodeBuildLogsOnSuccess ?? true; // default to true if not provided

const shouldApplyRepackOverrides = job.platform && job.mode === BuildMode.REPACK;
this._job = {
Expand Down
11 changes: 11 additions & 0 deletions packages/eas-build-job/src/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,14 @@ export const isGenericArtifact = <
}
return false;
};

export const isManagedArtifact = <
TSpec extends { type: GenericArtifactType | ManagedArtifactType },
>(
artifactSpec: TSpec
): artifactSpec is TSpec & { type: ManagedArtifactType } => {
if (Object.values(ManagedArtifactType).includes(artifactSpec.type as ManagedArtifactType)) {
return true;
}
return false;
};
12 changes: 7 additions & 5 deletions packages/local-build-plugin/src/android.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Android, ManagedArtifactType, BuildPhase, Env } from '@expo/eas-build-job';
import { Android, BuildPhase, Env, isManagedArtifact } from '@expo/eas-build-job';
import { Builders, BuildContext, Artifacts } from '@expo/build-tools';
import omit from 'lodash/omit';

Expand All @@ -23,10 +23,12 @@ export async function buildAndroidAsync(
logger,
logBuffer,
uploadArtifact: async ({ artifact, logger }) => {
if (artifact.type === ManagedArtifactType.APPLICATION_ARCHIVE) {
return await prepareArtifacts(artifact.paths, logger);
} else if (artifact.type === ManagedArtifactType.BUILD_ARTIFACTS) {
return await prepareArtifacts(artifact.paths, logger);
if (isManagedArtifact(artifact)) {
return await prepareArtifacts({
artifactPaths: artifact.paths,
logger,
artifactType: artifact.type,
});
} else {
return null;
}
Expand Down
26 changes: 23 additions & 3 deletions packages/local-build-plugin/src/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@ import path from 'path';
import { bunyan } from '@expo/logger';
import fs from 'fs-extra';
import * as tar from 'tar';
import { ManagedArtifactType } from '@expo/eas-build-job';

import config from './config';

export async function prepareArtifacts(artifactPaths: string[], logger?: bunyan): Promise<string> {
export async function prepareArtifacts({
artifactPaths,
artifactType,
logger,
}: {
artifactPaths: string[];
artifactType: ManagedArtifactType;
logger?: bunyan;
}): Promise<string> {
const l = logger?.child({ phase: 'PREPARE_ARTIFACTS' });
l?.info('Preparing artifacts');
let suffix;
Expand Down Expand Up @@ -35,10 +44,21 @@ export async function prepareArtifacts(artifactPaths: string[], logger?: bunyan)
suffix = '.tar.gz';
localPath = archivePath;
}
const artifactName = `build-${Date.now()}${suffix}`;
const artifactName =
artifactType === ManagedArtifactType.APPLICATION_ARCHIVE
? `build-${Date.now()}${suffix}`
: artifactType === ManagedArtifactType.BUILD_ARTIFACTS
? `artifacts-${Date.now()}${suffix}`
: `xcode-logs-${Date.now()}${suffix}`;
const destPath = config.artifactPath ?? path.join(config.artifactsDir, artifactName);
await fs.copy(localPath, destPath);
l?.info({ phase: 'PREPARE_ARTIFACTS' }, `Writing artifacts to ${destPath}`);
if (artifactType === ManagedArtifactType.APPLICATION_ARCHIVE) {
l?.info({ phase: 'PREPARE_ARTIFACTS' }, `Writing application archive to ${destPath}`);
} else if (artifactType === ManagedArtifactType.BUILD_ARTIFACTS) {
l?.info({ phase: 'PREPARE_ARTIFACTS' }, `Writing build artifacts to ${destPath}`);
} else {
l?.info({ phase: 'PREPARE_ARTIFACTS' }, `Writing Xcode logs to ${destPath}`);
}
return destPath;
}

Expand Down
13 changes: 8 additions & 5 deletions packages/local-build-plugin/src/ios.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ios, BuildPhase, Env, ManagedArtifactType } from '@expo/eas-build-job';
import { Ios, BuildPhase, Env, isManagedArtifact } from '@expo/eas-build-job';
import { Builders, BuildContext, Artifacts } from '@expo/build-tools';
import omit from 'lodash/omit';

Expand All @@ -23,17 +23,20 @@ export async function buildIosAsync(
logger,
logBuffer,
uploadArtifact: async ({ artifact, logger }) => {
if (artifact.type === ManagedArtifactType.APPLICATION_ARCHIVE) {
return await prepareArtifacts(artifact.paths, logger);
} else if (artifact.type === ManagedArtifactType.BUILD_ARTIFACTS) {
return await prepareArtifacts(artifact.paths, logger);
if (isManagedArtifact(artifact)) {
return await prepareArtifacts({
artifactPaths: artifact.paths,
logger,
artifactType: artifact.type,
});
} else {
return null;
}
},
env,
metadata,
skipNativeBuild: config.skipNativeBuild,
shouldUploadXcodeBuildLogsOnSuccess: false,
});

await ctx.runBuildPhase(BuildPhase.START_BUILD, async () => {
Expand Down

0 comments on commit 73b604c

Please sign in to comment.