From 1d2c9c61918939f2c951018a9ed024215f66327c Mon Sep 17 00:00:00 2001 From: James Greenhill Date: Wed, 1 Apr 2026 20:23:45 -0700 Subject: [PATCH 1/2] Restore AMD64 container builds with native runners Brings back linux/amd64 container images using a matrix build strategy with native runners for each architecture (no QEMU cross-compilation): - arm64: built on ubuntu-24.04-arm (existing) - amd64: built on ubuntu-24.04 (new) Both architectures build in parallel, then a manifest job merges them into multi-arch tags on ECR and GHCR. This keeps the per-arch build fast (~5min native vs ~20min QEMU) while restoring amd64 support. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/container-image-cd.yml | 76 ++++++++++++++++++++---- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/.github/workflows/container-image-cd.yml b/.github/workflows/container-image-cd.yml index e691e4e4..d3254af5 100644 --- a/.github/workflows/container-image-cd.yml +++ b/.github/workflows/container-image-cd.yml @@ -13,9 +13,17 @@ env: jobs: build: - name: Build and push duckgres + name: Build ${{ matrix.platform }} if: github.repository == 'PostHog/duckgres' - runs-on: ubuntu-24.04-arm + strategy: + fail-fast: false + matrix: + include: + - platform: linux/arm64 + runner: ubuntu-24.04-arm + - platform: linux/amd64 + runner: ubuntu-24.04 + runs-on: ${{ matrix.runner }} permissions: id-token: write contents: read @@ -45,23 +53,71 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push container image + - name: Prepare platform slug + id: slug + run: echo "arch=${PLATFORM#linux/}" >> "$GITHUB_OUTPUT" + env: + PLATFORM: ${{ matrix.platform }} + + - name: Build and push by digest id: build uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 with: context: . push: true - platforms: linux/arm64 + platforms: ${{ matrix.platform }} tags: | - ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:${{ github.sha }} - ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:latest + ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-${{ steps.slug.outputs.arch }} + ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:${{ github.sha }}-${{ steps.slug.outputs.arch }} build-args: | VERSION=build-${{ github.sha }} COMMIT=${{ github.sha }} BUILD_TAGS=kubernetes - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=${{ steps.slug.outputs.arch }} + cache-to: type=gha,mode=max,scope=${{ steps.slug.outputs.arch }} + + manifest: + name: Create multi-arch manifest + needs: build + if: github.repository == 'PostHog/duckgres' + runs-on: ubuntu-24.04 + permissions: + id-token: write + contents: read + packages: write + + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 + with: + role-to-assume: ${{ secrets.AWS_ECR_PUBLISH_IAM_ROLE }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 # v2.0.1 + + - name: Login to GHCR + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ${{ env.GHCR_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create and push ECR manifest + run: | + docker manifest create ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \ + ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64 \ + ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-amd64 + docker manifest push ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} + + - name: Create and push GHCR manifests + run: | + for tag in "${{ github.sha }}" "latest"; do + docker manifest create ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:${tag} \ + ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64 \ + ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:${{ github.sha }}-amd64 + docker manifest push ${{ env.GHCR_REGISTRY }}/posthog/${{ env.IMAGE_NAME }}:${tag} + done - name: Get deployer token id: deployer @@ -80,7 +136,7 @@ jobs: { "values": { "image": { - "sha": "${{ github.sha }}@${{ steps.build.outputs.digest }}" + "sha": "${{ github.sha }}" } }, "release": "duckgres", From fd7c52223084a71c3f6ef568fbc6dbbc8813435b Mon Sep 17 00:00:00 2001 From: James Greenhill Date: Wed, 1 Apr 2026 20:26:31 -0700 Subject: [PATCH 2/2] Fix: restore digest pin in deployment payload docker manifest push prints the manifest digest to stdout. Capture it and pass it through to the Charts deployment trigger so the deployed image is pinned to the exact multi-arch manifest that was built. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/container-image-cd.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/container-image-cd.yml b/.github/workflows/container-image-cd.yml index d3254af5..6fc1dbe2 100644 --- a/.github/workflows/container-image-cd.yml +++ b/.github/workflows/container-image-cd.yml @@ -104,11 +104,13 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Create and push ECR manifest + id: ecr-manifest run: | docker manifest create ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \ ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64 \ ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-amd64 - docker manifest push ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} + digest=$(docker manifest push ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}) + echo "digest=${digest}" >> "$GITHUB_OUTPUT" - name: Create and push GHCR manifests run: | @@ -136,7 +138,7 @@ jobs: { "values": { "image": { - "sha": "${{ github.sha }}" + "sha": "${{ github.sha }}@${{ steps.ecr-manifest.outputs.digest }}" } }, "release": "duckgres",