Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 17 additions & 30 deletions .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
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:
permissions: {}
needs: [ multiarch ]
runs-on: ubuntu-latest
steps:
- 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
with:
image_name: synapse
platforms: linux/amd64
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
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'
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
88 changes: 88 additions & 0 deletions .github/workflows/multiarch-build-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: multiarch-build-workflow
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i made this a reusable workflow since many repos at sentry seem to need the same thing. might extract it later.


# 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.
on:
workflow_call:
inputs:
image_name:
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:
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.
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 }}
# Each matrix leg stages a single arch as :sha-<arch>;
# 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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having GHCR images can be useful in sandboxes where we can't reach production images.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prod images are public. I've used it successfully in the sandbox here: https://github.com/getsentry/terraform-sandboxes.private/pull/427

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
Comment on lines +47 to +57
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The build-arch job unconditionally pushes images to the production Google Artifact Registry on every PR run because google_ar: true is hardcoded, ignoring the inputs.push condition.
Severity: MEDIUM

Suggested Fix

Add a condition to the getsentry/action-build-and-push-images step within the build-arch job to respect the inputs.push input. For example, change google_ar: true to google_ar: ${{ inputs.push }}. This will ensure images are only pushed to the production registry when intended.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .github/workflows/multiarch-build-workflow.yml#L42-L57

Potential issue: The `build-arch` job in the `multiarch-build-workflow.yml` workflow
unconditionally pushes per-architecture images to the production Google Artifact
Registry (GAR) on every pull request. The `getsentry/action-build-and-push-images` step
has `google_ar: true` hardcoded. While the workflow has an `inputs.push` parameter
intended to control this behavior, it is not used to gate the image push in the
`build-arch` job. This is a regression from the previous workflow, where pushing to GAR
was correctly conditioned on merges to the `main` branch, and will pollute the
production registry with intermediate images from every PR.

Did we get this right? 👍 / 👎 to inform future reviews.


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}"
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 []
Loading