diff --git a/ci/src/build-handler/index.mjs b/ci/src/build-handler/index.mjs index be73a4222..a0aa0186c 100644 --- a/ci/src/build-handler/index.mjs +++ b/ci/src/build-handler/index.mjs @@ -67,6 +67,40 @@ function eventIsPullRequest(event) { return false; } +/** + * + * @param {GitHubPullRequestWebhookPayload|GitHubPushWebhookPayload} event + * @param {string} buildspec + * @param {object} environmentVariables + * @param {string} projectName + * @param {object} extraEnvironmentVariables + */ +async function startBuild( + event, + buildspec, + environmentVariables, + projectName, + extraEnvironmentVariables, +) { + const environmentVariablesOverride = { + ...environmentVariables, + ...extraEnvironmentVariables, + }; + + return codebuild.send( + new StartBuildCommand({ + projectName, + sourceTypeOverride: 'GITHUB', + sourceLocationOverride: event.repository.clone_url, + sourceVersion: eventIsPullRequest(event) + ? `pr/${event.pull_request.number}` + : event.after, + buildspecOverride: buildspec, + environmentVariablesOverride, + }), + ); +} + /** * `startBuild` returns a Build object * https://docs.aws.amazon.com/codebuild/latest/APIReference/API_Build.html @@ -147,18 +181,40 @@ async function triggerBuild(ciContentsResponse, event) { environmentVariables.push({ name: 'PRX_GITHUB_AFTER', value: after }); } - await codebuild.send( - new StartBuildCommand({ - projectName: process.env.CODEBUILD_PROJECT_NAME, - sourceTypeOverride: 'GITHUB', - sourceLocationOverride: event.repository.clone_url, - sourceVersion: eventIsPullRequest(event) - ? `pr/${event.pull_request.number}` - : event.after, - buildspecOverride: buildspec, - environmentVariablesOverride: environmentVariables, - }), - ); + // If the buildspec explicitly specifies any architectures, only include the + // architectures listed + if ( + buildspec.includes('PRX_BUILD_X86_64') || + buildspec.includes('PRX_BUILD_AARCH64') + ) { + if (buildspec.includes('PRX_BUILD_X86_64')) { + await startBuild( + event, + buildspec, + environmentVariables, + process.env.X64_CODEBUILD_PROJECT_NAME, + { name: 'PRX_TARGET_ARCHITECTURE', value: 'x86_64' }, + ); + } + + if (buildspec.includes('PRX_BUILD_AARCH64')) { + await startBuild( + event, + buildspec, + environmentVariables, + process.env.ARM_CODEBUILD_PROJECT_NAME, + { name: 'PRX_TARGET_ARCHITECTURE', value: 'aarch64' }, + ); + } + } else { + await startBuild( + event, + buildspec, + environmentVariables, + process.env.X64_CODEBUILD_PROJECT_NAME, + { name: 'PRX_TARGET_ARCHITECTURE', value: 'x86_64' }, + ); + } console.log('CodeBuild started'); } diff --git a/ci/template.yml b/ci/template.yml index 328e36b57..1244c78e4 100644 --- a/ci/template.yml +++ b/ci/template.yml @@ -290,7 +290,8 @@ Resources: Environment: Variables: GITHUB_ACCESS_TOKEN: !Ref GitHubToken - CODEBUILD_PROJECT_NAME: !Ref CiCodeBuildProject + X64_CODEBUILD_PROJECT_NAME: !Ref CiCodeBuildProject + ARM_CODEBUILD_PROJECT_NAME: !Ref CiCodeBuildArmProject AWS_ACCOUNT_ID: !Ref AWS::AccountId Events: GitHubWebhook: diff --git a/ci/utility/post_build.sh b/ci/utility/post_build.sh index 3d342ee93..3d370d1a5 100755 --- a/ci/utility/post_build.sh +++ b/ci/utility/post_build.sh @@ -41,18 +41,20 @@ push_to_ecr() { fi set -e + arch="${PRX_TARGET_ARCHITECTURE}" + # e.g., github/prx/porter image_name="${safe_ecr_repo_name}" # e.g., 123456789012.dkr.ecr.us-east-1.amazonaws.com ecr_domain="${PRX_AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com" - # This is always just the Git commit hash - # e.g., de67a8d77768093b20a9ae961a78313a3c0ef096 - commit_image_tag="${PRX_COMMIT}" - # e.g., github/prx/porter:de67a8d77768093b20a9ae961a78313a3c0ef096 + # This is the Git commit hash with the architecture + # e.g., de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 + commit_image_tag="${PRX_COMMIT}-${arch}" + # e.g., github/prx/porter:de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 commit_tagged_image_name="${image_name}:${commit_image_tag}" - # 123456789012.dkr.ecr.us-east-1.amazonaws.com/github/prx/porter:de67a8d77768093b20a9ae961a78313a3c0ef096 + # 123456789012.dkr.ecr.us-east-1.amazonaws.com/github/prx/porter:de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 commit_full_image_uri="${ecr_domain}/${commit_tagged_image_name}" # PRX_CI_PUBLISH is the indicator that production artifacts should @@ -65,16 +67,16 @@ push_to_ecr() { # tag should include a `prerelease-` prefix. if [ "$PRX_CI_PUBLISH" = "true" ] then - # e.g., release-de67a8d77768093b20a9ae961a78313a3c0ef096 - prefix_image_tag="release-${PRX_COMMIT}" + # e.g., release-de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 + prefix_image_tag="release-${PRX_COMMIT}-${arch}" else - # e.g., prerelease-de67a8d77768093b20a9ae961a78313a3c0ef096 - prefix_image_tag="prerelease-${PRX_COMMIT}" + # e.g., prerelease-de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 + prefix_image_tag="prerelease-${PRX_COMMIT}-${arch}" fi - # e.g., github/prx/porter:release-de67a8d77768093b20a9ae961a78313a3c0ef096 + # e.g., github/prx/porter:release-de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 prefix_tagged_image_name="${image_name}:${prefix_image_tag}" - # 123456789012.dkr.ecr.us-east-1.amazonaws.com/github/prx/porter:release-de67a8d77768093b20a9ae961a78313a3c0ef096 + # 123456789012.dkr.ecr.us-east-1.amazonaws.com/github/prx/porter:release-de67a8d77768093b20a9ae961a78313a3c0ef096-aarch64 prefix_full_image_uri="${ecr_domain}/${prefix_tagged_image_name}" # Export a variable whose name is the LABEL from the Dockerfile, @@ -83,6 +85,10 @@ push_to_ecr() { # this would set WEB_SERVER=1234.dkr.ecr.us-eas-1.amazonaws.com... declare -gx "$label"="$commit_tagged_image_name" + # The image is tagged and pushed twice, which results in one image + # in ECR with both tags. The "commit" tag is what is used in + # Parameter Store, ECS tasks, etc, but the "prefix" tag is added + # so that ECR lifecycle rules can handle releases properly. echo "> Pushing image $image_id to ECR $commit_full_image_uri" docker tag $image_id $commit_full_image_uri docker push $commit_full_image_uri