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>
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' |