From 179158c53301531aba3eac3c0a6faea8432843eb Mon Sep 17 00:00:00 2001 From: Tahmid Ahmed Date: Fri, 2 Oct 2026 21:19:25 -0400 Subject: [PATCH] TAN-1032: build standup-bot arm64 natively on separate runner/repo instead of QEMU-emulated multi-platform standup-bot's Cargo.lock has 274 crates (serenity, tokio, hyper, reqwest). Building linux/arm64 via QEMU emulation in the same job as amd64 took over an hour on a cold cache. Split into a native-runner matrix instead: amd64 on ubuntu-latest, arm64 on ubuntu-24.04-arm, each building+pushing a single platform with no emulation. arm64 pushes to a separate codebloom-standup-bot-arm repository rather than merging into one multi-arch tag, since the deployed instance stays on amd64 until the planned arm64 node migration. codebloom (web) is unaffected: still one multi-platform buildx job. --- .../internal/standup-bot/action.yml | 5 ++++ .github/scripts/build-image/index.ts | 26 ++++++++++++++++--- .github/workflows/ci-cd.yml | 26 ++++++++++++++++--- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/.github/composite/build-image/internal/standup-bot/action.yml b/.github/composite/build-image/internal/standup-bot/action.yml index 434118293..9f154e0b2 100644 --- a/.github/composite/build-image/internal/standup-bot/action.yml +++ b/.github/composite/build-image/internal/standup-bot/action.yml @@ -13,6 +13,10 @@ inputs: description: "Boolean indicating whether the image should be uploaded to Docker registry or not." required: false default: true + ARCH: + description: "Target architecture to build natively (amd64 or arm64). Each arch pushes to its own Docker repository (codebloom-standup-bot / codebloom-standup-bot-arm)." + required: false + default: amd64 outputs: tag: @@ -44,5 +48,6 @@ runs: --docker-upload="${{ inputs.DOCKER_UPLOAD }}" \ --getGhaOutput=true \ --type="standup-bot" \ + --arch="${{ inputs.ARCH }}" \ --environment="${{ inputs.ENVIRONMENT }}" \ --prId="${{ github.event.pull_request.number }}" diff --git a/.github/scripts/build-image/index.ts b/.github/scripts/build-image/index.ts index d828c47e5..63cb72ba2 100644 --- a/.github/scripts/build-image/index.ts +++ b/.github/scripts/build-image/index.ts @@ -16,6 +16,7 @@ const { getGhaOutput, githubOutputFile, type, + arch, prId, } = await yargs(hideBin(process.argv)) .option("environment", { @@ -45,6 +46,12 @@ const { demandOption: true, default: "web" as Type, }) + .option("arch", { + choices: ["amd64", "arm64"] as const, + describe: + "Target architecture for type=standup-bot (built natively per-arch, one repo per arch); ignored for type=web, which always builds both in one multi-platform job", + default: "amd64" as const, + }) .option("prId", { type: "string", default: "", @@ -55,6 +62,17 @@ const { const tagPrefix = environment === "staging" ? "staging-" : ""; +// `web` always builds both platforms in one multi-platform buildx job. +// `standup-bot` builds natively per-arch (no QEMU) to a separate repo per +// arch instead, since it has a large enough dependency tree that emulated +// compiles are impractically slow. +const dockerRepository = + type === "web" ? "codebloom" + : arch === "arm64" ? "codebloom-standup-bot-arm" + : "codebloom-standup-bot"; +const platforms = + type === "web" ? ["linux/amd64", "linux/arm64"] : [`linux/${arch}`]; + async function main() { const { dockerHubPat, @@ -122,13 +140,13 @@ async function main() { }; await dockerClient.buildImage({ - dockerRepository: type === "web" ? "codebloom" : "codebloom-standup-bot", + dockerRepository, dockerFileLocation: type === "web" ? "infra/Dockerfile" : "internal/standup-bot/Dockerfile", tags, shouldUpload: dockerUpload, buildArgs, - platforms: ["linux/amd64", "linux/arm64"], + platforms, }); console.log("Image pushed successfully."); @@ -151,9 +169,9 @@ async function main() { prId, owner: "Patina-Network", repository: "codebloom", - message: `The image has been uploaded to https://hub.docker.com/r/patinanetwork/${type === "web" ? "codebloom" : "codebloom-standup-bot"}/tags under the following tags: + message: `The image has been uploaded to https://hub.docker.com/r/patinanetwork/${dockerRepository}/tags under the following tags: -${tags.map((t) => `- \`${type === "web" ? "codebloom" : "codebloom-standup-bot"}:${t}\``).join("\n")} +${tags.map((t) => `- \`${dockerRepository}:${t}\``).join("\n")} `, }); } diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d4b106751..081099c85 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -125,11 +125,19 @@ jobs: DOCKER_UPLOAD: "true" buildStagingStandupBotImage: - name: Build staging image for codebloom-standup-bot - runs-on: ubuntu-latest + name: Build staging image for codebloom-standup-bot (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} if: github.ref_name != 'main' + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm + steps: - name: Checkout repository uses: actions/checkout@v6 @@ -140,6 +148,7 @@ jobs: SECRETS: ${{ toJSON(secrets) }} ENVIRONMENT: staging DOCKER_UPLOAD: "true" + ARCH: ${{ matrix.arch }} validateDBSchema: name: Validate DB Schema on Prod DB @@ -176,11 +185,19 @@ jobs: SECRETS: ${{ toJSON(secrets) }} buildStandupBotImage: - name: Build codebloom-standup-bot Docker Image & Upload to Registry - runs-on: ubuntu-latest + name: Build codebloom-standup-bot Docker Image & Upload to Registry (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} if: github.ref_name == 'main' + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm + steps: - name: Checkout repository uses: actions/checkout@v6 @@ -189,6 +206,7 @@ jobs: uses: ./.github/composite/build-image/internal/standup-bot with: SECRETS: ${{ toJSON(secrets) }} + ARCH: ${{ matrix.arch }} deploy: name: deploy codebloom to K8S