carlos / platform Public

objstore: pin minio image + mc download in CI, fail loud on health timeout

Review fix-up for 35e3ff8:

- quay.io/minio/minio was unpinned (floating latest) and
  dl.min.io/.../linux-amd64/mc always resolves to the newest mc build —
  both can break minio-contract with zero repo change (mc's own
  admin-policy syntax has churned across versions before). Pinned to
  quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z (verified live against
  the quay.io tag API: its manifest digest is identical to :latest as of
  2026-08-10) and the matching mc build via its archive URL,
  mc.RELEASE.2025-08-13T08-35-41Z (verified live against the minio/mc
  GitHub releases API and a HEAD on the dl.min.io archive URL). Both pins
  carry a YAML comment on how they were verified and how to re-verify
  before bumping.
- The 30-iteration minio health poll fell through silently on timeout,
  surfacing later as an opaque mc alias error. It now exits 1 with
  "minio never became healthy after 30s" (plus docker logs) when the
  loop exhausts.

Verified locally: ci.yml parses as YAML (pyyaml), full gate green
(go build/vet/test -count=1 across all 21 packages, gofmt -l clean,
GOOS=darwin build clean). The pinned image/mc combination and the new
timeout-exit path are themselves only exercised by CI's first run — same
no-docker caveat as 35e3ff8.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 09a14d65b46dc51b80bbc13e8b19af310d582f69 parent 35e3ff8
1 file changed, +28 −3
  • .github/workflows/ci.yml +28 −3
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 46acb187c..e65c7670b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -86,14 +86,39 @@ jobs:
go-version-file: go.mod
cache: true
- name: start minio
+ # Pinned rather than :latest — everything else in this file pins
+ # (go-version-file, action majors), and a floating minio tag has
+ # already broken this exact job class once (mc's own admin-policy
+ # syntax churned across versions). Verified live against the quay.io
+ # registry API on 2026-08-10: RELEASE.2025-09-07T16-13-09Z is the
+ # image quay.io/minio/minio:latest currently resolves to (identical
+ # manifest digest sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e).
+ # Bump deliberately, not silently — re-verify against
+ # https://quay.io/api/v1/repository/minio/minio/tag/ before moving it.
run: |
docker run -d --name minio -p 9000:9000 \
-e MINIO_ROOT_USER=root -e MINIO_ROOT_PASSWORD=rootsecret \
- quay.io/minio/minio server /data
- for i in $(seq 1 30); do curl -sf http://127.0.0.1:9000/minio/health/live && break; sleep 1; done
+ quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z server /data
+ for i in $(seq 1 30); do
+ if curl -sf http://127.0.0.1:9000/minio/health/live; then
+ break
+ fi
+ if [ "$i" -eq 30 ]; then
+ echo "minio never became healthy after 30s" >&2
+ docker logs minio || true
+ exit 1
+ fi
+ sleep 1
+ done
- name: mint scoped user
run: |
- curl -sfL https://dl.min.io/client/mc/release/linux-amd64/mc -o mc && chmod +x mc
+ # Pinned to the mc release published alongside the minio server
+ # image above (verified live against the minio/mc GitHub releases
+ # API and dl.min.io's archive endpoint on 2026-08-10) rather than
+ # the floating linux-amd64/mc path, for the same reproducibility
+ # reason. Bump together with the minio image pin above.
+ curl -sfL https://dl.min.io/client/mc/release/linux-amd64/archive/mc.RELEASE.2025-08-13T08-35-41Z -o mc && chmod +x mc
+ ./mc --version
./mc alias set local http://127.0.0.1:9000 root rootsecret
./mc mb local/contract-bucket local/denied-bucket
cat > /tmp/policy.json <<'EOF'