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
16 changes: 16 additions & 0 deletions .github/ci/minio/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# CI-only AMD64 image. Versions match the development Compose services.
# Upstream registries deny pulls; official release binaries remain available.
FROM alpine:3.22.6@sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8

LABEL org.opencontainers.image.source="https://github.com/block/buzz" \
org.opencontainers.image.title="Buzz CI MinIO" \
org.opencontainers.image.licenses="AGPL-3.0-only"

RUN apk add --no-cache ca-certificates curl

ADD --checksum=sha256:7c5bd8512c6e966455b1d198209358b2d191c77a83ab377c4073281065fb855f --chmod=755 \
https://github.com/minio/minio/releases/download/RELEASE.2025-09-07T16-13-09Z/minio.linux-amd64.RELEASE.2025-09-07T16-13-09Z /usr/local/bin/minio
ADD --checksum=sha256:01f866e9c5f9b87c2b09116fa5d7c06695b106242d829a8bb32990c00312e891 --chmod=755 \
https://github.com/minio/mc/releases/download/RELEASE.2025-08-13T08-35-41Z/mc.linux-amd64.RELEASE.2025-08-13T08-35-41Z /usr/local/bin/mc

ENTRYPOINT ["minio"]
51 changes: 51 additions & 0 deletions .github/ci/minio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Buzz CI MinIO

`ghcr.io/block/buzz-minio:latest` contains MinIO and `mc` for the disposable
Linux AMD64 CI runners. `docker-compose.ci.yml` selects it for both services;
development and deployment defaults stay in `docker-compose.yml`.

The **MinIO image** workflow builds only when its inputs change, or on a manual
dispatch. Pull requests build and smoke-test without publishing. On `main`, a
successful smoke test publishes the same image as
`sha-<full commit>-run-<run id>-<attempt>` and `latest`. The run-specific tag
preserves each build, including package refreshes from the same source commit.
Once consumers adopt the override, ordinary CI only pulls it; there is no build
fallback or dependency on the publisher. `latest` deliberately floats, and
Compose always pulls it. Docker's pull output records the resolved digest.

The Dockerfile uses the same upstream releases as the development services,
with checksummed official GitHub release binaries and a digest-pinned Alpine
base. MinIO and `mc` are AGPL-3.0; their corresponding source is available at
the [MinIO release](https://github.com/minio/minio/tree/RELEASE.2025-09-07T16-13-09Z)
and [mc release](https://github.com/minio/mc/tree/RELEASE.2025-08-13T08-35-41Z).

## First publication

The image must exist and be publicly pullable before the CI switch can pass.
Use two separate PRs: Buzz only permits squash merges, so two commits in one
PR cannot stage this rollout.

1. Merge the publisher-only PR containing `.github/ci/minio/`,
`.github/workflows/minio-image.yml`, and the opt-in `docker-compose.ci.yml`.
Ordinary CI does not select the override yet, so it does not need this image
to validate the publisher PR. The merge triggers the first publication.
2. After publication succeeds, an org/package admin must make **buzz-minio**
public in its GitHub package settings (new GHCR packages default to private,
even for public repositories). Verify an anonymous pull of
`ghcr.io/block/buzz-minio:latest`.
3. Rebase the separate consumer PR onto `main`, run its integration checks, and
merge it. That PR selects the override in relay and mesh lifecycle CI.

Subsequent publications preserve package visibility.

## Updating or rebuilding

Update the release URLs/checksums or base digest in the Dockerfile and open a
PR. Merging triggers publication. To rebuild the existing recipe (for example,
to pick up Alpine package updates), dispatch **MinIO image** from `main`.
Manual dispatch disables Docker's layer cache so the package installation
runs again. Other refs can build and test but cannot publish `latest`.

To reproduce a CI run with a recorded version, set `MINIO_CI_IMAGE` to
the published run-specific tag or digest while using
`COMPOSE_FILE=docker-compose.yml:docker-compose.ci.yml`.
27 changes: 27 additions & 0 deletions .github/ci/minio/smoke-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Run on a disposable Docker host with the CI Compose files and a built image.
set -euo pipefail
: "${MINIO_CI_IMAGE:?Set MINIO_CI_IMAGE to the locally built image}"
: "${COMPOSE_FILE:?Select docker-compose.yml and docker-compose.ci.yml}"

# Exercise the real healthcheck and initializer without pulling over the image
# under test. No application services or tests need a MinIO build step.
docker compose up -d --wait --wait-timeout 90 --pull never minio
docker compose run --rm --no-deps --pull never minio-init
docker compose exec -T minio sh -eu -c '
minio --version
mc --version
mc alias set local http://localhost:9000 buzz_dev buzz_dev_secret
printf "buzz-minio-smoke\n" > /tmp/expected
mc cp /tmp/expected local/buzz-media/smoke-test
mc cat local/buzz-media/smoke-test > /tmp/actual
cmp /tmp/expected /tmp/actual
status=$(curl --silent --show-error --output /dev/null --write-out "%{http_code}" \
http://localhost:9000/buzz-media/smoke-test)
test "$status" = 403
mc rm local/buzz-media/smoke-test
if mc stat local/buzz-media/smoke-test; then
echo "Deleted object is still present" >&2
exit 1
fi
'
6 changes: 6 additions & 0 deletions .github/workflows/_ci-relay.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ jobs:
--archive-file target/ci/postgres-tests.tar.zst

desktop-e2e-integration-shard:
env:
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
name: Desktop E2E Integration (${{ matrix.shard }}/2)
runs-on: ubuntu-latest
timeout-minutes: 20
Expand Down Expand Up @@ -400,6 +402,8 @@ jobs:
echo "Desktop E2E Integration shards passed"

backend-integration:
env:
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
name: Backend Integration (relay e2e)
runs-on: ubuntu-latest
timeout-minutes: 20
Expand Down Expand Up @@ -541,6 +545,8 @@ jobs:
if-no-files-found: ignore

relay-e2e:
env:
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
name: Relay E2E
runs-on: ubuntu-latest
timeout-minutes: 20
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ jobs:
- 'deny.toml'
- '.github/workflows/ci.yml'
- '.github/workflows/_ci-*.yml'
- 'docker-compose.yml'
- 'docker-compose.ci.yml'
- 'scripts/run-tests.sh'
- 'scripts/model-capabilities.json'
- 'scripts/normative-corpus.json'
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/mesh-lifecycle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ on:
- 'scripts/ci-mesh-lifecycle-smoke.sh'
- 'scripts/start-relay-for-tests.sh'
- '.github/workflows/mesh-lifecycle.yml'
- 'docker-compose.yml'
- 'docker-compose.ci.yml'
pull_request:
paths:
- 'crates/buzz-relay/examples/mesh_*.rs'
Expand All @@ -34,6 +36,8 @@ on:
- 'scripts/ci-mesh-lifecycle-smoke.sh'
- 'scripts/start-relay-for-tests.sh'
- '.github/workflows/mesh-lifecycle.yml'
- 'docker-compose.yml'
- 'docker-compose.ci.yml'
workflow_dispatch:

concurrency:
Expand All @@ -45,6 +49,8 @@ env:

jobs:
lifecycle-smoke:
env:
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
name: Relay-Driven Mesh Lifecycle Smoke
runs-on: ubuntu-24.04
timeout-minutes: 45
Expand Down
80 changes: 80 additions & 0 deletions .github/workflows/minio-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: MinIO image

# A separate publisher, never a dependency of ordinary CI. Image changes get
# a build/smoke test on PRs; only reviewed main commits can move :latest.
on:
push:
branches: [main]
paths:
- '.github/ci/minio/**'
- '.github/workflows/minio-image.yml'
- 'docker-compose.yml'
- 'docker-compose.ci.yml'
pull_request:
paths:
- '.github/ci/minio/**'
- '.github/workflows/minio-image.yml'
- 'docker-compose.yml'
- 'docker-compose.ci.yml'
workflow_dispatch:

concurrency:
group: minio-image-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

env:
IMAGE_NAME: ghcr.io/block/buzz-minio
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
MINIO_CI_IMAGE: ghcr.io/block/buzz-minio:sha-${{ github.sha }}-run-${{ github.run_id }}-${{ github.run_attempt }}

jobs:
image:
name: Build and smoke-test MinIO
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .github/ci/minio
platforms: linux/amd64
load: true
tags: ${{ env.MINIO_CI_IMAGE }}
labels: org.opencontainers.image.revision=${{ github.sha }}
# A maintenance dispatch must refresh apk packages even with a warm
# layer cache. Normal image changes can still reuse cached layers.
no-cache: ${{ github.event_name == 'workflow_dispatch' }}
cache-from: type=gha,scope=minio
cache-to: type=gha,scope=minio,mode=max
- name: Smoke-test CI services
run: bash .github/ci/minio/smoke-test.sh
- name: Clean up smoke test
if: always()
run: docker compose down --volumes
- name: Log in to GHCR
if: github.repository == 'block/buzz' && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Publish tested image
if: github.repository == 'block/buzz' && github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
run: |
docker push "$MINIO_CI_IMAGE"
docker tag "$MINIO_CI_IMAGE" "$IMAGE_NAME:latest"
docker push "$IMAGE_NAME:latest"
{
echo "Published $MINIO_CI_IMAGE and $IMAGE_NAME:latest"
echo 'First publication: make the buzz-minio package public before enabling CI consumers.'
} >> "$GITHUB_STEP_SUMMARY"
2 changes: 2 additions & 0 deletions deploy/charts/buzz/ci/quickstart-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ redis:
enabled: true
minio:
enabled: true
image: ghcr.io/block/buzz-minio:latest
mcImage: ghcr.io/block/buzz-minio:latest
relayUrl: wss://buzz.test.local
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000001"
relay:
Expand Down
12 changes: 12 additions & 0 deletions docker-compose.ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# CI pulls the published image; only minio-image.yml builds it.
# MINIO_CI_IMAGE lets the publisher smoke-test an unpublished image or an
# operator reproduce a run with its recorded run-specific tag/digest.
services:
minio:
image: ${MINIO_CI_IMAGE:-ghcr.io/block/buzz-minio:latest}
platform: linux/amd64
pull_policy: always
minio-init:
image: ${MINIO_CI_IMAGE:-ghcr.io/block/buzz-minio:latest}
platform: linux/amd64
pull_policy: always
Loading