From b66d514d8fa36ee406a59bd1decfcf6222e98531 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 14:10:48 -0700 Subject: [PATCH 1/9] build: Build multiarch image Add linux/arm64 to the build-docker-image workflow alongside linux/amd64 so the published image runs natively on Apple Silicon. This enables Sentry staff to more easily run on M-series mac. --- .github/workflows/build-docker-image.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 04b9ab7..a8e1647 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -21,7 +21,7 @@ jobs: uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 with: image_name: synapse - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 ghcr: false tag_nightly: false @@ -30,7 +30,7 @@ jobs: uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 with: image_name: synapse - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 google_ar: true google_ar_image_name: us-docker.pkg.dev/sentryio/synapse/image ghcr: false From 3fcc2e193b877a0a27006cabf41e30c96b1c39fc Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 14:48:36 -0700 Subject: [PATCH 2/9] update libzstd copy to support multiarch --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 54dd92f..dedb422 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,12 +18,14 @@ COPY shared ./shared RUN cargo build --release +RUN mkdir /stage && cp --parents /usr/lib/$(gcc -print-multiarch)/libzstd.so.1 /stage + # Runtime stage FROM gcr.io/distroless/cc-debian13:nonroot WORKDIR /app COPY --from=builder /app/target/release/synapse synapse -COPY --from=builder /usr/lib/x86_64-linux-gnu/libzstd.so.1 /usr/lib/x86_64-linux-gnu/libzstd.so.1 +COPY --from=builder /stage/ / ENTRYPOINT ["/app/synapse"] CMD [] From b72e5f6f639abfb6625d8215b813b2a83e6f46f4 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 15:50:09 -0700 Subject: [PATCH 3/9] add arm64 benchmark --- .github/workflows/arm64-bench.yml | 28 ++++++++++++++++++++++++ .github/workflows/build-docker-image.yml | 3 --- 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/arm64-bench.yml diff --git a/.github/workflows/arm64-bench.yml b/.github/workflows/arm64-bench.yml new file mode 100644 index 0000000..a085d85 --- /dev/null +++ b/.github/workflows/arm64-bench.yml @@ -0,0 +1,28 @@ +name: arm64-bench +on: + workflow_dispatch: + push: + branches: [ devservices-multiarch ] + +jobs: + bench-native: + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 + with: + image_name: synapse + platforms: linux/arm64 + ghcr: false + tag_nightly: false + + bench-qemu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 + with: + image_name: synapse + platforms: linux/arm64 + ghcr: false + tag_nightly: false diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index a8e1647..d1b7232 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -13,9 +13,6 @@ jobs: - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - - name: Docker build - pull request if: github.event_name == 'pull_request' uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 From 8752d8ff460cd2e10e08622669a5f59e1fcdfe03 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 15:54:10 -0700 Subject: [PATCH 4/9] permissions --- .github/workflows/arm64-bench.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/arm64-bench.yml b/.github/workflows/arm64-bench.yml index a085d85..d139ba2 100644 --- a/.github/workflows/arm64-bench.yml +++ b/.github/workflows/arm64-bench.yml @@ -1,4 +1,6 @@ name: arm64-bench +permissions: + contents: read on: workflow_dispatch: push: From 743f4c8fc1045af82729ec7ccf410fe7906a9b92 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 16:43:48 -0700 Subject: [PATCH 5/9] rewrite using native runner --- .github/workflows/arm64-bench.yml | 30 ------- .github/workflows/build-docker-image.yml | 43 ++++----- .../workflows/multiarch-build-workflow.yml | 88 +++++++++++++++++++ 3 files changed, 104 insertions(+), 57 deletions(-) delete mode 100644 .github/workflows/arm64-bench.yml create mode 100644 .github/workflows/multiarch-build-workflow.yml diff --git a/.github/workflows/arm64-bench.yml b/.github/workflows/arm64-bench.yml deleted file mode 100644 index d139ba2..0000000 --- a/.github/workflows/arm64-bench.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: arm64-bench -permissions: - contents: read -on: - workflow_dispatch: - push: - branches: [ devservices-multiarch ] - -jobs: - bench-native: - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 - with: - image_name: synapse - platforms: linux/arm64 - ghcr: false - tag_nightly: false - - bench-qemu: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 - with: - image_name: synapse - platforms: linux/arm64 - ghcr: false - tag_nightly: false diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index d1b7232..141de86 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -1,36 +1,25 @@ name: build-docker-image -permissions: - contents: read - id-token: write on: push: branches: [ main ] pull_request: + jobs: + multiarch: + permissions: + contents: read + id-token: write + uses: ./.github/workflows/multiarch-build-workflow.yml + with: + image_name: synapse + google_ar_image_name: us-docker.pkg.dev/sentryio/synapse/image + google_workload_identity_provider: projects/868781662168/locations/global/workloadIdentityPools/prod-github/providers/github-oidc-pool + google_service_account: gha-gcr-push@sac-prod-sa.iam.gserviceaccount.com + push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + + # Gate job — keeps `build-docker` as a single branch-protection check. build-docker: + needs: [ multiarch ] runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - - - name: Docker build - pull request - if: github.event_name == 'pull_request' - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 - with: - image_name: synapse - platforms: linux/amd64,linux/arm64 - ghcr: false - tag_nightly: false - - - name: Docker build - push to registry - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 - with: - image_name: synapse - platforms: linux/amd64,linux/arm64 - google_ar: true - google_ar_image_name: us-docker.pkg.dev/sentryio/synapse/image - ghcr: false - tag_nightly: false - google_workload_identity_provider: projects/868781662168/locations/global/workloadIdentityPools/prod-github/providers/github-oidc-pool - google_service_account: gha-gcr-push@sac-prod-sa.iam.gserviceaccount.com + - run: 'true' diff --git a/.github/workflows/multiarch-build-workflow.yml b/.github/workflows/multiarch-build-workflow.yml new file mode 100644 index 0000000..04177b0 --- /dev/null +++ b/.github/workflows/multiarch-build-workflow.yml @@ -0,0 +1,88 @@ +name: multiarch-build-workflow + +# Reusable workflow: matrix-builds a Dockerfile per-arch on native runners +# via getsentry/action-build-and-push-images, then assembles a multi-arch +# manifest from the per-arch suffixed tags. +# +# Scope: GAR-only for now. GHCR / multi-registry can be added when the +# pattern is upstreamed into getsentry/action-build-and-push-images. + +on: + workflow_call: + inputs: + image_name: + description: Image name (matches the wrapper's image_name input). + required: true + type: string + google_ar_image_name: + description: Fully-qualified GAR image path (e.g. us-docker.pkg.dev/sentryio/synapse/image). + required: true + type: string + push: + description: Whether to assemble the manifest. The wrapper itself decides whether per-arch images get pushed; this only gates the assemble step. Caller typically computes from event/ref. + type: boolean + default: false + google_workload_identity_provider: + required: true + type: string + google_service_account: + required: true + type: string + +jobs: + build-arch: + strategy: + fail-fast: false + matrix: + include: + - { platform: linux/amd64, runner: ubuntu-latest, pair: amd64 } + - { platform: linux/arm64, runner: ubuntu-24.04-arm, pair: arm64 } + runs-on: ${{ matrix.runner }} + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: getsentry/action-build-and-push-images@8fc75e483c09a68721f2c8951292ee17f8821766 + with: + image_name: ${{ inputs.image_name }} + platforms: ${{ matrix.platform }} + tag_suffix: -${{ matrix.pair }} + ghcr: false + google_ar: true + google_ar_image_name: ${{ inputs.google_ar_image_name }} + google_workload_identity_provider: ${{ inputs.google_workload_identity_provider }} + google_service_account: ${{ inputs.google_service_account }} + tag_latest: false + tag_nightly: false + + assemble: + needs: [ build-arch ] + if: inputs.push + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: google-github-actions/auth@ba79af03959ebeac9769e648f473a284504d9193 # v2.1.10 + with: + workload_identity_provider: ${{ inputs.google_workload_identity_provider }} + service_account: ${{ inputs.google_service_account }} + + - env: + IMAGE: ${{ inputs.google_ar_image_name }} + run: gcloud auth configure-docker "$(echo "$IMAGE" | cut -d/ -f1)" + + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + + - name: Assemble manifest + env: + IMAGE: ${{ inputs.google_ar_image_name }} + SHA: ${{ github.sha }} + run: | + docker buildx imagetools create \ + -t "${IMAGE}:${SHA}" \ + -t "${IMAGE}:latest" \ + "${IMAGE}:${SHA}-amd64" \ + "${IMAGE}:${SHA}-arm64" + docker buildx imagetools inspect "${IMAGE}:${SHA}" From 95a0296b7f12867a3535ec72fd589fc5447ca333 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 16:45:15 -0700 Subject: [PATCH 6/9] . --- .github/workflows/multiarch-build-workflow.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/multiarch-build-workflow.yml b/.github/workflows/multiarch-build-workflow.yml index 04177b0..220d6db 100644 --- a/.github/workflows/multiarch-build-workflow.yml +++ b/.github/workflows/multiarch-build-workflow.yml @@ -3,10 +3,6 @@ name: multiarch-build-workflow # Reusable workflow: matrix-builds a Dockerfile per-arch on native runners # via getsentry/action-build-and-push-images, then assembles a multi-arch # manifest from the per-arch suffixed tags. -# -# Scope: GAR-only for now. GHCR / multi-registry can be added when the -# pattern is upstreamed into getsentry/action-build-and-push-images. - on: workflow_call: inputs: From 3a96a8b8dd69d7600883f98d89b3da9460a2af61 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 16:49:44 -0700 Subject: [PATCH 7/9] add comments --- .github/workflows/multiarch-build-workflow.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/multiarch-build-workflow.yml b/.github/workflows/multiarch-build-workflow.yml index 220d6db..bf923dd 100644 --- a/.github/workflows/multiarch-build-workflow.yml +++ b/.github/workflows/multiarch-build-workflow.yml @@ -43,12 +43,16 @@ jobs: with: image_name: ${{ inputs.image_name }} platforms: ${{ matrix.platform }} + # Each matrix leg stages a single arch as :sha-; + # the assemble job stitches them into the multi-arch :sha and :latest. + # This is the same as Snuba's multiarch workflow. tag_suffix: -${{ matrix.pair }} ghcr: false google_ar: true google_ar_image_name: ${{ inputs.google_ar_image_name }} google_workload_identity_provider: ${{ inputs.google_workload_identity_provider }} google_service_account: ${{ inputs.google_service_account }} + # latest/nightly belong on the assembled manifest, not per-arch. tag_latest: false tag_nightly: false From f689b464cfa068b4cc505144da324f10a53f9eae Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 16:51:10 -0700 Subject: [PATCH 8/9] permissions --- .github/workflows/build-docker-image.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 141de86..47f6a8d 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -19,6 +19,7 @@ jobs: # Gate job — keeps `build-docker` as a single branch-protection check. build-docker: + permissions: {} needs: [ multiarch ] runs-on: ubuntu-latest steps: From d29c9bd4a63f337fa2303fd55d39ae15b9be77c7 Mon Sep 17 00:00:00 2001 From: Lyn Nagara Date: Thu, 7 May 2026 17:21:25 -0700 Subject: [PATCH 9/9] update descriptions --- .github/workflows/multiarch-build-workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/multiarch-build-workflow.yml b/.github/workflows/multiarch-build-workflow.yml index bf923dd..3ed07e6 100644 --- a/.github/workflows/multiarch-build-workflow.yml +++ b/.github/workflows/multiarch-build-workflow.yml @@ -7,7 +7,7 @@ on: workflow_call: inputs: image_name: - description: Image name (matches the wrapper's image_name input). + description: Only feeds GHCR naming in the underlying action; unused here since ghcr is disabled, but still required by the action. required: true type: string google_ar_image_name: @@ -15,7 +15,7 @@ on: required: true type: string push: - description: Whether to assemble the manifest. The wrapper itself decides whether per-arch images get pushed; this only gates the assemble step. Caller typically computes from event/ref. + description: Whether to assemble the manifest. type: boolean default: false google_workload_identity_provider: