From 28c4b0a7fa5945a26f57fc23c51394b48fe385af Mon Sep 17 00:00:00 2001 From: Will Schurman Date: Thu, 19 Sep 2024 11:09:33 -0700 Subject: [PATCH] [continuous-deploy-fingeprint] Output whether each platform build was created or one was reused (#306) --- build/continuous-deploy-fingerprint/index.js | 90 +++++++++++------- continuous-deploy-fingerprint/action.yml | 8 +- src/actions/continuous-deploy-fingerprint.ts | 99 ++++++++++++-------- 3 files changed, 120 insertions(+), 77 deletions(-) diff --git a/build/continuous-deploy-fingerprint/index.js b/build/continuous-deploy-fingerprint/index.js index 1692964f..8398b729 100644 --- a/build/continuous-deploy-fingerprint/index.js +++ b/build/continuous-deploy-fingerprint/index.js @@ -44559,39 +44559,52 @@ async function continuousDeployFingerprintAction(input = collectContinuousDeploy (0, core_1.info)(`Android fingerprint: ${androidFingerprintHash}`); (0, core_1.info)(`iOS fingerprint: ${iosFingerprintHash}`); (0, core_1.info)('Looking for builds with matching runtime version (fingerprint)...'); - let androidBuildInfo = await getBuildInfoWithFingerprintAsync({ + const existingAndroidBuildInfo = await getBuildInfoWithFingerprintAsync({ cwd: input.workingDirectory, platform: 'android', profile: input.profile, fingerprintHash: androidFingerprintHash, excludeExpiredBuilds: isInPullRequest, }); - if (androidBuildInfo) { - (0, core_1.info)(`Existing Android build found with matching fingerprint: ${androidBuildInfo.id}`); + let androidBuildRunInfo; + if (existingAndroidBuildInfo) { + (0, core_1.info)(`Existing Android build found with matching fingerprint: ${existingAndroidBuildInfo.id}`); + androidBuildRunInfo = { buildInfo: existingAndroidBuildInfo, isNew: false }; } else { (0, core_1.info)(`No existing Android build found for fingerprint, starting a new build...`); - androidBuildInfo = await createEASBuildAsync({ - cwd: input.workingDirectory, - platform: 'android', - profile: input.profile, - }); + androidBuildRunInfo = { + buildInfo: await createEASBuildAsync({ + cwd: input.workingDirectory, + platform: 'android', + profile: input.profile, + }), + isNew: true, + }; } - let iosBuildInfo = await getBuildInfoWithFingerprintAsync({ + const existingIosBuildInfo = await getBuildInfoWithFingerprintAsync({ cwd: input.workingDirectory, platform: 'ios', profile: input.profile, fingerprintHash: iosFingerprintHash, excludeExpiredBuilds: isInPullRequest, }); - if (iosBuildInfo) { - (0, core_1.info)(`Existing iOS build found with matching fingerprint: ${iosBuildInfo.id}`); + let iosBuildRunInfo; + if (existingIosBuildInfo) { + (0, core_1.info)(`Existing iOS build found with matching fingerprint: ${existingIosBuildInfo.id}`); + iosBuildRunInfo = { buildInfo: existingIosBuildInfo, isNew: false }; } else { (0, core_1.info)(`No existing iOS build found for fingerprint, starting a new build...`); - iosBuildInfo = await createEASBuildAsync({ cwd: input.workingDirectory, platform: 'ios', profile: input.profile }); + iosBuildRunInfo = { + buildInfo: await createEASBuildAsync({ + cwd: input.workingDirectory, + platform: 'ios', + profile: input.profile, + }), + isNew: true, + }; } - const builds = [androidBuildInfo, iosBuildInfo]; (0, core_1.info)(`Publishing EAS Update...`); const updates = await publishEASUpdatesAsync({ cwd: input.workingDirectory, @@ -44602,7 +44615,13 @@ async function continuousDeployFingerprintAction(input = collectContinuousDeploy } else { const messageId = `continuous-deploy-fingerprint-projectId:${projectId}`; - const messageBody = createSummaryForUpdatesAndBuilds({ config, projectId, updates, builds, options: input }); + const messageBody = createSummaryForUpdatesAndBuilds({ + config, + projectId, + updates, + buildRunInfos: { androidBuildRunInfo, iosBuildRunInfo }, + options: input, + }); await (0, github_1.createIssueComment)({ ...(0, github_1.pullContext)(), token: input.githubToken, @@ -44612,8 +44631,10 @@ async function continuousDeployFingerprintAction(input = collectContinuousDeploy } (0, core_1.setOutput)('android-fingerprint', androidFingerprintHash); (0, core_1.setOutput)('ios-fingerprint', iosFingerprintHash); - (0, core_1.setOutput)('android-build-id', androidBuildInfo.id); - (0, core_1.setOutput)('ios-build-id', iosBuildInfo.id); + (0, core_1.setOutput)('android-build-id', androidBuildRunInfo.buildInfo.id); + (0, core_1.setOutput)('android-did-start-new-build', androidBuildRunInfo.isNew); + (0, core_1.setOutput)('ios-build-id', iosBuildRunInfo.buildInfo.id); + (0, core_1.setOutput)('ios-did-start-new-build', iosBuildRunInfo.isNew); (0, core_1.setOutput)('update-output', updates); } exports.continuousDeployFingerprintAction = continuousDeployFingerprintAction; @@ -44701,32 +44722,29 @@ async function publishEASUpdatesAsync({ cwd, branch }) { } return JSON.parse(stdout); } -function createSummaryForUpdatesAndBuilds({ config, projectId, updates, builds, options, }) { +function createSummaryForUpdatesAndBuilds({ config, projectId, updates, buildRunInfos, options, }) { const appSlug = config.slug; const qrTarget = (0, comment_1.getQrTarget)(options); const appSchemes = (0, comment_1.getSchemesInOrderFromConfig)(config) || []; - const androidBuild = builds.find(build => build.platform === expo_1.AppPlatform.Android); - const iosBuild = builds.find(build => build.platform === expo_1.AppPlatform.Ios); + const { androidBuildRunInfo, iosBuildRunInfo } = buildRunInfos; const androidUpdate = updates.find(update => update.platform === 'android'); const iosUpdate = updates.find(update => update.platform === 'ios'); const getBuildLink = (build) => build ? `[Build Permalink](${(0, expo_1.getBuildLogsUrl)(build)})` : 'n/a'; const getUpdateLink = (update) => update ? `[Update Permalink](${(0, eas_1.getUpdateGroupWebsite)({ projectId, updateGroupId: update.group })})` : 'n/a'; const getUpdateQRURL = (update) => update ? (0, eas_1.getUpdateGroupQr)({ projectId, updateGroupId: update.group, appSlug, qrTarget }) : null; - const getBuildDetails = (build) => build - ? getBuildLink(build) + - '
' + - (0, comment_1.createDetails)({ - summary: 'Details', - details: [ - `Distribution: \`${build.distribution}\``, - `Build profile: \`${build.buildProfile}\``, - `Runtime version: \`${build.runtimeVersion}\``, - `App version: \`${build.appVersion}\``, - `Git commit: \`${build.gitCommitHash}\``, - ].join('
'), - delim: '', - }) - : 'n/a'; + const getBuildDetails = (buildRunInfo) => getBuildLink(buildRunInfo.buildInfo) + + '
' + + (0, comment_1.createDetails)({ + summary: 'Details', + details: [ + `Distribution: \`${buildRunInfo.buildInfo.distribution}\``, + `Build profile: \`${buildRunInfo.buildInfo.buildProfile}\``, + `Runtime version: \`${buildRunInfo.buildInfo.runtimeVersion}\``, + `App version: \`${buildRunInfo.buildInfo.appVersion}\``, + `Git commit: \`${buildRunInfo.buildInfo.gitCommitHash}\``, + ].join('
'), + delim: '', + }); const getUpdateDetails = (update) => update ? getUpdateLink(update) + '
' + @@ -44761,8 +44779,8 @@ ${schemesMessage}   | ${expo_1.appPlatformEmojis[expo_1.AppPlatform.Android]} Android | ${expo_1.appPlatformEmojis[expo_1.AppPlatform.Ios]} iOS --- | --- | --- -Fingerprint | ${androidBuild?.runtimeVersion ?? 'n/a'} | ${iosBuild?.runtimeVersion ?? 'n/a'} -Build Details | ${getBuildDetails(androidBuild)} | ${getBuildDetails(iosBuild)} +Fingerprint | ${androidBuildRunInfo.buildInfo.runtimeVersion ?? 'n/a'} | ${iosBuildRunInfo.buildInfo.runtimeVersion ?? 'n/a'} +Build Details | ${getBuildDetails(androidBuildRunInfo)} | ${getBuildDetails(iosBuildRunInfo)} Update Details | ${getUpdateDetails(androidUpdate)} | ${getUpdateDetails(iosUpdate)} Update QR | ${androidQr ?? 'n/a'} | ${iosQr ?? 'n/a'} `; diff --git a/continuous-deploy-fingerprint/action.yml b/continuous-deploy-fingerprint/action.yml index 2ec47c64..07593f95 100644 --- a/continuous-deploy-fingerprint/action.yml +++ b/continuous-deploy-fingerprint/action.yml @@ -30,8 +30,12 @@ outputs: ios-fingerprint: description: The iOS fingerprint of the current commit. android-build-id: - description: ID for Android EAS Build if one was started + description: ID for Android EAS Build with matching fingerprint. + android-did-start-new-build: + description: Whether this run of the action started a new Android EAS Build. ios-build-id: - description: ID for iOS EAS Build if one was started. + description: ID for iOS EAS Build with matching fingerprint. + ios-did-start-new-build: + description: Whether this run of the action started a new iOS EAS Build. update-output: description: The output (JSON) from the `eas update` command diff --git a/src/actions/continuous-deploy-fingerprint.ts b/src/actions/continuous-deploy-fingerprint.ts index b53c308d..35b70a04 100644 --- a/src/actions/continuous-deploy-fingerprint.ts +++ b/src/actions/continuous-deploy-fingerprint.ts @@ -10,6 +10,8 @@ import { createIssueComment, hasPullContext, pullContext } from '../github'; import { loadProjectConfig } from '../project'; import { executeAction } from '../worker'; +type BuildRunInfo = { buildInfo: BuildInfo; isNew: boolean }; + export function collectContinuousDeployFingerprintInput() { return { profile: getInput('profile'), @@ -41,40 +43,52 @@ export async function continuousDeployFingerprintAction(input = collectContinuou info('Looking for builds with matching runtime version (fingerprint)...'); - let androidBuildInfo = await getBuildInfoWithFingerprintAsync({ + const existingAndroidBuildInfo = await getBuildInfoWithFingerprintAsync({ cwd: input.workingDirectory, platform: 'android', profile: input.profile, fingerprintHash: androidFingerprintHash, excludeExpiredBuilds: isInPullRequest, }); - if (androidBuildInfo) { - info(`Existing Android build found with matching fingerprint: ${androidBuildInfo.id}`); + let androidBuildRunInfo: BuildRunInfo; + if (existingAndroidBuildInfo) { + info(`Existing Android build found with matching fingerprint: ${existingAndroidBuildInfo.id}`); + androidBuildRunInfo = { buildInfo: existingAndroidBuildInfo, isNew: false }; } else { info(`No existing Android build found for fingerprint, starting a new build...`); - androidBuildInfo = await createEASBuildAsync({ - cwd: input.workingDirectory, - platform: 'android', - profile: input.profile, - }); + androidBuildRunInfo = { + buildInfo: await createEASBuildAsync({ + cwd: input.workingDirectory, + platform: 'android', + profile: input.profile, + }), + isNew: true, + }; } - let iosBuildInfo = await getBuildInfoWithFingerprintAsync({ + const existingIosBuildInfo = await getBuildInfoWithFingerprintAsync({ cwd: input.workingDirectory, platform: 'ios', profile: input.profile, fingerprintHash: iosFingerprintHash, excludeExpiredBuilds: isInPullRequest, }); - if (iosBuildInfo) { - info(`Existing iOS build found with matching fingerprint: ${iosBuildInfo.id}`); + let iosBuildRunInfo: BuildRunInfo; + if (existingIosBuildInfo) { + info(`Existing iOS build found with matching fingerprint: ${existingIosBuildInfo.id}`); + iosBuildRunInfo = { buildInfo: existingIosBuildInfo, isNew: false }; } else { info(`No existing iOS build found for fingerprint, starting a new build...`); - iosBuildInfo = await createEASBuildAsync({ cwd: input.workingDirectory, platform: 'ios', profile: input.profile }); + iosBuildRunInfo = { + buildInfo: await createEASBuildAsync({ + cwd: input.workingDirectory, + platform: 'ios', + profile: input.profile, + }), + isNew: true, + }; } - const builds = [androidBuildInfo, iosBuildInfo]; - info(`Publishing EAS Update...`); const updates = await publishEASUpdatesAsync({ @@ -86,7 +100,13 @@ export async function continuousDeployFingerprintAction(input = collectContinuou info(`Skipped comment: action was not run from a pull request`); } else { const messageId = `continuous-deploy-fingerprint-projectId:${projectId}`; - const messageBody = createSummaryForUpdatesAndBuilds({ config, projectId, updates, builds, options: input }); + const messageBody = createSummaryForUpdatesAndBuilds({ + config, + projectId, + updates, + buildRunInfos: { androidBuildRunInfo, iosBuildRunInfo }, + options: input, + }); await createIssueComment({ ...pullContext(), @@ -98,8 +118,10 @@ export async function continuousDeployFingerprintAction(input = collectContinuou setOutput('android-fingerprint', androidFingerprintHash); setOutput('ios-fingerprint', iosFingerprintHash); - setOutput('android-build-id', androidBuildInfo.id); - setOutput('ios-build-id', iosBuildInfo.id); + setOutput('android-build-id', androidBuildRunInfo.buildInfo.id); + setOutput('android-did-start-new-build', androidBuildRunInfo.isNew); + setOutput('ios-build-id', iosBuildRunInfo.buildInfo.id); + setOutput('ios-did-start-new-build', iosBuildRunInfo.isNew); setOutput('update-output', updates); } @@ -241,21 +263,20 @@ function createSummaryForUpdatesAndBuilds({ config, projectId, updates, - builds, + buildRunInfos, options, }: { config: ExpoConfig; projectId: string; updates: EasUpdate[]; - builds: BuildInfo[]; + buildRunInfos: { androidBuildRunInfo: BuildRunInfo; iosBuildRunInfo: BuildRunInfo }; options: { qrTarget?: 'expo-go' | 'dev-build' | 'dev-client'; workingDirectory: string }; }) { const appSlug = config.slug; const qrTarget = getQrTarget(options); const appSchemes = getSchemesInOrderFromConfig(config) || []; - const androidBuild = builds.find(build => build.platform === AppPlatform.Android); - const iosBuild = builds.find(build => build.platform === AppPlatform.Ios); + const { androidBuildRunInfo, iosBuildRunInfo } = buildRunInfos; const androidUpdate = updates.find(update => update.platform === 'android'); const iosUpdate = updates.find(update => update.platform === 'ios'); @@ -266,22 +287,20 @@ function createSummaryForUpdatesAndBuilds({ update ? `[Update Permalink](${getUpdateGroupWebsite({ projectId, updateGroupId: update.group })})` : 'n/a'; const getUpdateQRURL = (update: EasUpdate | undefined) => update ? getUpdateGroupQr({ projectId, updateGroupId: update.group, appSlug, qrTarget }) : null; - const getBuildDetails = (build: BuildInfo | undefined) => - build - ? getBuildLink(build) + - '
' + - createDetails({ - summary: 'Details', - details: [ - `Distribution: \`${build.distribution}\``, - `Build profile: \`${build.buildProfile}\``, - `Runtime version: \`${build.runtimeVersion}\``, - `App version: \`${build.appVersion}\``, - `Git commit: \`${build.gitCommitHash}\``, - ].join('
'), - delim: '', - }) - : 'n/a'; + const getBuildDetails = (buildRunInfo: BuildRunInfo) => + getBuildLink(buildRunInfo.buildInfo) + + '
' + + createDetails({ + summary: 'Details', + details: [ + `Distribution: \`${buildRunInfo.buildInfo.distribution}\``, + `Build profile: \`${buildRunInfo.buildInfo.buildProfile}\``, + `Runtime version: \`${buildRunInfo.buildInfo.runtimeVersion}\``, + `App version: \`${buildRunInfo.buildInfo.appVersion}\``, + `Git commit: \`${buildRunInfo.buildInfo.gitCommitHash}\``, + ].join('
'), + delim: '', + }); const getUpdateDetails = (update: EasUpdate | undefined) => update ? getUpdateLink(update) + @@ -323,8 +342,10 @@ ${schemesMessage}   | ${appPlatformEmojis[AppPlatform.Android]} Android | ${appPlatformEmojis[AppPlatform.Ios]} iOS --- | --- | --- -Fingerprint | ${androidBuild?.runtimeVersion ?? 'n/a'} | ${iosBuild?.runtimeVersion ?? 'n/a'} -Build Details | ${getBuildDetails(androidBuild)} | ${getBuildDetails(iosBuild)} +Fingerprint | ${androidBuildRunInfo.buildInfo.runtimeVersion ?? 'n/a'} | ${ + iosBuildRunInfo.buildInfo.runtimeVersion ?? 'n/a' + } +Build Details | ${getBuildDetails(androidBuildRunInfo)} | ${getBuildDetails(iosBuildRunInfo)} Update Details | ${getUpdateDetails(androidUpdate)} | ${getUpdateDetails(iosUpdate)} Update QR | ${androidQr ?? 'n/a'} | ${iosQr ?? 'n/a'} `;