diff --git a/packages/build-tools/src/builders/common.ts b/packages/build-tools/src/builders/common.ts index 387eedf1..c6e829b9 100644 --- a/packages/build-tools/src/builders/common.ts +++ b/packages/build-tools/src/builders/common.ts @@ -34,6 +34,7 @@ export async function runBuilderWithHooksAsync( if (ctx.job.platform === Platform.IOS) { await findAndUploadXcodeBuildLogsAsync(ctx as BuildContext, { logger: ctx.logger, + runStatus: buildSuccess ? 'success' : 'errored', }); } diff --git a/packages/build-tools/src/builders/custom.ts b/packages/build-tools/src/builders/custom.ts index 916e5ed3..e9c3e48e 100644 --- a/packages/build-tools/src/builders/custom.ts +++ b/packages/build-tools/src/builders/custom.ts @@ -56,20 +56,29 @@ export async function runCustomBuildAsync(ctx: BuildContext): Promise< } }); try { - try { - await workflow.executeAsync(); - } finally { - if (!ctx.artifacts.XCODE_BUILD_LOGS && ctx.job.platform === Platform.IOS) { - try { - await findAndUploadXcodeBuildLogsAsync(ctx as BuildContext, { - logger: ctx.logger, - }); - } catch { - // do nothing, it's a non-breaking error. - } + await workflow.executeAsync(); + + if (!ctx.artifacts.XCODE_BUILD_LOGS && ctx.job.platform === Platform.IOS) { + try { + await findAndUploadXcodeBuildLogsAsync(ctx as BuildContext, { + logger: ctx.logger, + runStatus: 'success', + }); + } catch { + // do nothing, it's a non-breaking error. } } } catch (err: any) { + if (!ctx.artifacts.XCODE_BUILD_LOGS && ctx.job.platform === Platform.IOS) { + try { + await findAndUploadXcodeBuildLogsAsync(ctx as BuildContext, { + logger: ctx.logger, + runStatus: 'errored', + }); + } catch { + // do nothing, it's a non-breaking error. + } + } err.artifacts = ctx.artifacts; throw err; } diff --git a/packages/build-tools/src/context.ts b/packages/build-tools/src/context.ts index 57ae90d8..221852a5 100644 --- a/packages/build-tools/src/context.ts +++ b/packages/build-tools/src/context.ts @@ -38,9 +38,14 @@ export interface LogBuffer { export type ArtifactToUpload = | { - type: ManagedArtifactType; + type: ManagedArtifactType.APPLICATION_ARCHIVE | ManagedArtifactType.BUILD_ARTIFACTS; paths: string[]; } + | { + type: ManagedArtifactType.XCODE_BUILD_LOGS; + paths: string[]; + runStatus: 'success' | 'errored'; + } | { type: GenericArtifactType; key: string; diff --git a/packages/build-tools/src/ios/xcodeBuildLogs.ts b/packages/build-tools/src/ios/xcodeBuildLogs.ts index d1758a79..92be4621 100644 --- a/packages/build-tools/src/ios/xcodeBuildLogs.ts +++ b/packages/build-tools/src/ios/xcodeBuildLogs.ts @@ -9,7 +9,7 @@ import { BuildContext } from '../context'; export async function findAndUploadXcodeBuildLogsAsync( ctx: BuildContext, - { logger }: { logger: bunyan } + { logger, runStatus }: { logger: bunyan; runStatus: 'success' | 'errored' } ): Promise { try { const xcodeBuildLogsPath = await findXcodeBuildLogsPathAsync(ctx.buildLogsDirectory); @@ -18,6 +18,7 @@ export async function findAndUploadXcodeBuildLogsAsync( artifact: { type: ManagedArtifactType.XCODE_BUILD_LOGS, paths: [xcodeBuildLogsPath], + runStatus, }, logger, }); diff --git a/packages/build-tools/src/steps/functions/findAndUploadBuildArtifacts.ts b/packages/build-tools/src/steps/functions/findAndUploadBuildArtifacts.ts index 6abb02d0..e3352a28 100644 --- a/packages/build-tools/src/steps/functions/findAndUploadBuildArtifacts.ts +++ b/packages/build-tools/src/steps/functions/findAndUploadBuildArtifacts.ts @@ -148,6 +148,7 @@ async function uploadXcodeBuildLogs({ artifact: { type: ManagedArtifactType.XCODE_BUILD_LOGS, paths: [xcodeBuildLogsPath], + runStatus: global.hasAnyPreviousStepFailed ? 'errored' : 'success', }, logger, }); diff --git a/packages/build-tools/src/steps/functions/uploadArtifact.ts b/packages/build-tools/src/steps/functions/uploadArtifact.ts index dedf9a05..1e35d8b3 100644 --- a/packages/build-tools/src/steps/functions/uploadArtifact.ts +++ b/packages/build-tools/src/steps/functions/uploadArtifact.ts @@ -92,11 +92,19 @@ export function createUploadArtifactBuildFunction(ctx: CustomBuildContext): Buil throw result.reason; }); - const artifact = { - type: parseArtifactTypeInput(`${inputs.type.value}`), - paths: artifactPaths, - key: inputs.key.value as string, - }; + const artifactType = parseArtifactTypeInput(`${inputs.type.value}`); + const artifact = + artifactType === ManagedArtifactType.XCODE_BUILD_LOGS + ? ({ + type: artifactType, + paths: artifactPaths, + runStatus: global.hasAnyPreviousStepFailed ? 'errored' : 'success', + } as const) + : { + type: artifactType, + paths: artifactPaths, + key: inputs.key.value as string, + }; try { await ctx.runtimeApi.uploadArtifact({ diff --git a/packages/eas-build-job/src/artifacts.ts b/packages/eas-build-job/src/artifacts.ts index 643176e3..be13d983 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 1763e31c..37fed2e8 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 846dcbd1..fa1d7ffc 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 54ea1756..bf234a96 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, ManagedArtifactType } from '@expo/eas-build-job'; import { Builders, BuildContext, Artifacts } from '@expo/build-tools'; import omit from 'lodash/omit'; @@ -23,10 +23,18 @@ 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)) { + if ( + artifact.type === ManagedArtifactType.XCODE_BUILD_LOGS && + artifact.runStatus !== 'errored' + ) { + return null; + } + return await prepareArtifacts({ + artifactPaths: artifact.paths, + logger, + artifactType: artifact.type, + }); } else { return null; }