From bc3bab8a424dae58e3d53542329de70895077594 Mon Sep 17 00:00:00 2001 From: kert Date: Fri, 11 Sep 2026 17:53:42 -0400 Subject: [PATCH] fix(infra,ci): mc base image moved to quay.io (docker.io/minio/mc is gone); failure-issue step bootstraps uv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Infra CI's mc job has failed on every push since docker.io/minio/mc started returning 'pull access denied, repository does not exist' — and nobody heard, because the generated File-failure-issue step ran `uv run` in a job that never installs uv ("uv: command not found", swallowed by the trailing || true). Pin quay.io/minio/mc to a release tag; the filer installs uv when it is missing. --- .gitea/workflows/ci.yml | 10 ++++++++ .gitea/workflows/deploy.yml | 30 ++++++++++++++++++++++ .gitea/workflows/harden.yml | 5 ++++ .gitea/workflows/infra-ci.yml | 30 ++++++++++++++++++++++ .gitea/workflows/llm-golden.yml | 5 ++++ .gitea/workflows/notebooks-integration.yml | 5 ++++ .gitea/workflows/rebuild-all.yml | 5 ++++ .gitea/workflows/release.yml | 5 ++++ .gitea/workflows/zotero-sync.yml | 5 ++++ dev/scripts/backends/gitea.py | 5 ++++ infra/images/mc.Dockerfile | 5 +++- 11 files changed, 109 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 83a68d9..2b56870 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -66,6 +66,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "CI" --job "test" \ @@ -108,6 +113,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "CI" --job "notebooks-smoke" \ diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index ee7ea44..d269c8e 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -50,6 +50,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Deploy" --job "notebooks" \ @@ -98,6 +103,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Deploy" --job "zotero" \ @@ -146,6 +156,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Deploy" --job "docs" \ @@ -195,6 +210,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Deploy" --job "api" \ @@ -244,6 +264,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Deploy" --job "llm" \ @@ -286,6 +311,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Deploy" --job "mc" \ diff --git a/.gitea/workflows/harden.yml b/.gitea/workflows/harden.yml index 65489ba..993a480 100644 --- a/.gitea/workflows/harden.yml +++ b/.gitea/workflows/harden.yml @@ -117,6 +117,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Harden" --job "build-scan-report" \ diff --git a/.gitea/workflows/infra-ci.yml b/.gitea/workflows/infra-ci.yml index de79b05..7d6464f 100644 --- a/.gitea/workflows/infra-ci.yml +++ b/.gitea/workflows/infra-ci.yml @@ -64,6 +64,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Infra CI" --job "notebooks" \ @@ -92,6 +97,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Infra CI" --job "zotero" \ @@ -120,6 +130,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Infra CI" --job "docs" \ @@ -148,6 +163,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Infra CI" --job "api" \ @@ -176,6 +196,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Infra CI" --job "llm" \ @@ -204,6 +229,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Infra CI" --job "mc" \ diff --git a/.gitea/workflows/llm-golden.yml b/.gitea/workflows/llm-golden.yml index 4a0e8d5..6d10662 100644 --- a/.gitea/workflows/llm-golden.yml +++ b/.gitea/workflows/llm-golden.yml @@ -54,6 +54,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "LLM Golden" --job "llm-golden" \ diff --git a/.gitea/workflows/notebooks-integration.yml b/.gitea/workflows/notebooks-integration.yml index 2f76491..935eee6 100644 --- a/.gitea/workflows/notebooks-integration.yml +++ b/.gitea/workflows/notebooks-integration.yml @@ -49,6 +49,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Notebooks Integration" --job "notebooks-integration" \ diff --git a/.gitea/workflows/rebuild-all.yml b/.gitea/workflows/rebuild-all.yml index c3997ac..7eb6a93 100644 --- a/.gitea/workflows/rebuild-all.yml +++ b/.gitea/workflows/rebuild-all.yml @@ -115,6 +115,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Rebuild All" --job "build-scan-report" \ diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 2488685..90e6ec1 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -34,6 +34,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Release" --job "release" \ diff --git a/.gitea/workflows/zotero-sync.yml b/.gitea/workflows/zotero-sync.yml index 0c71171..690ed2e 100644 --- a/.gitea/workflows/zotero-sync.yml +++ b/.gitea/workflows/zotero-sync.yml @@ -51,6 +51,11 @@ jobs: env: GITEA_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \ --workflow "Zotero Sync" --job "zotero-sync" \ diff --git a/dev/scripts/backends/gitea.py b/dev/scripts/backends/gitea.py index ae10d4b..24ae924 100644 --- a/dev/scripts/backends/gitea.py +++ b/dev/scripts/backends/gitea.py @@ -109,6 +109,11 @@ def _failure_step(workflow_name: str, job_name: str) -> str: env: GITEA_TOKEN: ${{{{ secrets.DEPLOY_TOKEN }}}} run: | + # Jobs that never install uv (image builds, infra checks) still + # need it here — otherwise the filer dies with "uv: command not + # found" and the failure is never filed. + command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" uv sync --no-dev --quiet 2>/dev/null || true uv run python -m api.diag.ci \\ --workflow "{workflow_name}" --job "{job_name}" \\ diff --git a/infra/images/mc.Dockerfile b/infra/images/mc.Dockerfile index c31a6e1..78e7d37 100644 --- a/infra/images/mc.Dockerfile +++ b/infra/images/mc.Dockerfile @@ -1,7 +1,10 @@ # syntax=docker/dockerfile:1 # MinIO Client (mc) sidecar — least-privilege admin helper for RustFS. +# The image moved off Docker Hub (docker.io/minio/mc now 404s — pull access +# denied) to quay.io; pinned to a release tag so a base-image change is a +# reviewed diff, not a silent CI break. # Runs as non-root, read-only filesystem, no capabilities. -FROM minio/mc:latest AS mc +FROM quay.io/minio/mc:RELEASE.2025-08-13T08-35-41Z AS mc FROM alpine:3 RUN addgroup -g 10002 -S mc && adduser -u 10002 -S mc -G mc