From 73b604c09b550df6c4c5dde3fbb5a73f4292b2b0 Mon Sep 17 00:00:00 2001 From: Szymon Dziedzic Date: Mon, 14 Oct 2024 08:32:51 +0200 Subject: [PATCH] [local-build-plugin][build-tools][eas-build-job] copy Xcode build logs to target destination on local iOS build failure to simplify debuging --- packages/build-tools/src/builders/common.ts | 5 +++- packages/build-tools/src/context.ts | 3 +++ packages/eas-build-job/src/artifacts.ts | 11 +++++++++ packages/local-build-plugin/src/android.ts | 12 +++++---- packages/local-build-plugin/src/artifacts.ts | 26 +++++++++++++++++--- packages/local-build-plugin/src/ios.ts | 13 ++++++---- 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/packages/build-tools/src/builders/common.ts b/packages/build-tools/src/builders/common.ts index 387eedf1e..6d2ecc65e 100644 --- a/packages/build-tools/src/builders/common.ts +++ b/packages/build-tools/src/builders/common.ts @@ -31,7 +31,10 @@ export async function runBuilderWithHooksAsync( }); }); - if (ctx.job.platform === Platform.IOS) { + if ( + ctx.job.platform === Platform.IOS && + (!buildSuccess || (buildSuccess && ctx.shouldUploadXcodeBuildLogsOnSuccess)) + ) { await findAndUploadXcodeBuildLogsAsync(ctx as BuildContext, { logger: ctx.logger, }); diff --git a/packages/build-tools/src/context.ts b/packages/build-tools/src/context.ts index 57ae90d80..66467106a 100644 --- a/packages/build-tools/src/context.ts +++ b/packages/build-tools/src/context.ts @@ -62,6 +62,7 @@ export interface BuildContextOptions { reportBuildPhaseStats?: (stats: BuildPhaseStats) => void; skipNativeBuild?: boolean; metadata?: Metadata; + shouldUploadXcodeBuildLogsOnSuccess?: boolean; } export class SkipNativeBuildError extends Error {} @@ -77,6 +78,7 @@ export class BuildContext { options?: { tags?: Record; extras?: Record } ) => void; public readonly skipNativeBuild?: boolean; + public readonly shouldUploadXcodeBuildLogsOnSuccess: boolean; public artifacts: Artifacts = {}; private _env: Env; @@ -98,6 +100,7 @@ export class BuildContext { 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 = { diff --git a/packages/eas-build-job/src/artifacts.ts b/packages/eas-build-job/src/artifacts.ts index 643176e3f..be13d983b 100644 --- a/packages/eas-build-job/src/artifacts.ts +++ b/packages/eas-build-job/src/artifacts.ts @@ -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; +}; diff --git a/packages/local-build-plugin/src/android.ts b/packages/local-build-plugin/src/android.ts index 1763e31c2..37fed2e8b 100644 --- a/packages/local-build-plugin/src/android.ts +++ b/packages/local-build-plugin/src/android.ts @@ -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'; @@ -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; } diff --git a/packages/local-build-plugin/src/artifacts.ts b/packages/local-build-plugin/src/artifacts.ts index 846dcbd12..fa1d7ffcd 100644 --- a/packages/local-build-plugin/src/artifacts.ts +++ b/packages/local-build-plugin/src/artifacts.ts @@ -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 { +export async function prepareArtifacts({ + artifactPaths, + artifactType, + logger, +}: { + artifactPaths: string[]; + artifactType: ManagedArtifactType; + logger?: bunyan; +}): Promise { const l = logger?.child({ phase: 'PREPARE_ARTIFACTS' }); l?.info('Preparing artifacts'); let suffix; @@ -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; } diff --git a/packages/local-build-plugin/src/ios.ts b/packages/local-build-plugin/src/ios.ts index 54ea1756c..5f8d1c1c8 100644 --- a/packages/local-build-plugin/src/ios.ts +++ b/packages/local-build-plugin/src/ios.ts @@ -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'; @@ -23,10 +23,12 @@ 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; } @@ -34,6 +36,7 @@ export async function buildIosAsync( env, metadata, skipNativeBuild: config.skipNativeBuild, + shouldUploadXcodeBuildLogsOnSuccess: false, }); await ctx.runBuildPhase(BuildPhase.START_BUILD, async () => {