From 6fbff83592cf79c312538c8cc5b66a0bad7c6426 Mon Sep 17 00:00:00 2001 From: jubnl Date: Wed, 19 Aug 2026 22:22:39 +0200 Subject: [PATCH] ci(server): make live-MinIO contract runs manual-only (AIStor licensing) MinIO's community line is discontinued entirely; the maintained successor, AIStor, requires a license key that can't safely live in a shared CI runner. The s3-contract CI job is removed; live-provider contract runs against MinIO/AIStor are now a manual, license-gated procedure documented in docker-compose.minio-test.yml's header. --- .github/workflows/test.yml | 58 ----------------------------------- .gitignore | 3 ++ README.md | 2 +- docker-compose.minio-test.yml | 50 ++++++++++++++++++++++++------ 4 files changed, 45 insertions(+), 68 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index df70e4ff8..6785e180a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -175,64 +175,6 @@ jobs: path: server/coverage/ retention-days: 7 - s3-contract: - name: S3 Driver Contract (MinIO) - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - - - name: Install dependencies - run: npm ci - - - name: Ensure @swc/core's Linux binary for unplugin-swc - # The lockfile was generated on Windows and omits @swc/core's Linux - # optional native binary, so npm ci/install skips it on the runner. - # Install the matching version explicitly so the server's SWC transform - # (server/vitest.config.ts) can load. - run: | - SWC_VERSION=$(node -p "require('@swc/core/package.json').version") - npm install --no-save --legacy-peer-deps "@swc/core-linux-x64-gnu@$SWC_VERSION" - - - name: Build shared - run: npm run build --workspace=shared - - - name: Start MinIO - # `services:` can't pass the `server /data` command to minio/minio, so - # the container starts via docker run. Tag pinned — quay.io is the - # maintained registry (Docker Hub minio/minio is archived). 127.0.0.1 - # endpoint is load-bearing: aws-lite picks path-style only for IP/localhost - # hosts, which is all stock MinIO speaks. - run: | - docker run -d --name minio -p 127.0.0.1:9000:9000 \ - -e MINIO_ROOT_USER=trekci -e MINIO_ROOT_PASSWORD=trekci-secret \ - quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z.hotfix.7aa24e772 server /data - - - name: Wait for MinIO - # curl was removed from the MinIO image — poll from the runner instead. - run: | - for i in $(seq 1 30); do - curl -sf http://127.0.0.1:9000/minio/health/live && exit 0 - sleep 1 - done - echo "MinIO never became healthy" >&2 - docker logs minio >&2 - exit 1 - - - name: Run the S3 driver contract suite - env: - TREK_TEST_S3_ENDPOINT: http://127.0.0.1:9000 - TREK_TEST_S3_BUCKET: trek-test - TREK_TEST_S3_ACCESS_KEY_ID: trekci - TREK_TEST_S3_SECRET_ACCESS_KEY: trekci-secret - run: cd server && npx vitest run tests/unit/nest/storage/s3.driver.contract.test.ts - client-quality: # Split out of client-tests: the suite takes ~11 minutes, and having the # gates in front of it meant a single lint finding threw away the whole test diff --git a/.gitignore b/.gitignore index fa3baa3aa..c3aaa38a2 100644 --- a/.gitignore +++ b/.gitignore @@ -65,5 +65,8 @@ coverage-*/ .scannerwork test-data +# Live-MinIO/AIStor manual test license key — never commit, operators obtain their own free key +minio-licence.key + .run .full-review diff --git a/README.md b/README.md index c12a2e528..6249a5c0f 100644 --- a/README.md +++ b/README.md @@ -508,7 +508,7 @@ Caddy handles TLS and WebSockets automatically. ### Off-box backups (S3) -You can mirror backups to any S3-compatible store (AWS S3, Cloudflare R2, Backblaze B2, Garage, MinIO — we pull MinIO from quay.io since the Docker Hub repo is archived; Garage is the maintained self-host alternative). Replica failures are logged and surfaced, never fail the request. Media categories on S3 are functional but unoptimized (every served byte proxies through the server; no HTTP Range on the proxy path). Switching a populated category's backend does not move existing objects. AWS caveat: Object-Lock buckets or checksum-requiring bucket policies reject the server's checksum-less uploads. Reference `docker-compose.minio-test.yml` for running the contract suite locally. +You can mirror backups to any S3-compatible store (AWS S3, Cloudflare R2, Backblaze B2, Garage, MinIO — MinIO's community line is discontinued entirely (both the archived Docker Hub repo and quay.io get no further updates); the maintained successor, AIStor, requires a license key, so Garage is the maintained self-host alternative without that requirement). Replica failures are logged and surfaced, never fail the request. Media categories on S3 are functional but unoptimized (every served byte proxies through the server; no HTTP Range on the proxy path). Switching a populated category's backend does not move existing objects. AWS caveat: Object-Lock buckets or checksum-requiring bucket policies reject the server's checksum-less uploads. Running the contract suite against a live MinIO/AIStor is a manual, license-gated procedure — see `docker-compose.minio-test.yml`'s header for the full setup and run steps; it is not part of CI. To mirror backups, configure the mirror backend via SQL: diff --git a/docker-compose.minio-test.yml b/docker-compose.minio-test.yml index aeb7a6612..f99a252e8 100644 --- a/docker-compose.minio-test.yml +++ b/docker-compose.minio-test.yml @@ -1,21 +1,53 @@ -# Local MinIO for the env-gated S3 driver contract suite: +# Manual, license-gated live-provider test for the env-gated S3 driver +# contract suite. This is NOT run in CI. +# +# Why manual: MinIO fully dropped the community line (quay.io/minio/minio +# gets no further updates). The maintained successor is AIStor +# (quay.io/minio/aistor/minio), which requires a license key to boot at all. +# A CI job can't hold a shared license credential safely, so live-provider +# contract runs are a manual, operator-driven procedure until a +# licensing-compatible target for CI exists (e.g. Garage). +# +# REQUIRED: a `minio-licence.key` file at the repo root (same directory as +# this compose file). It is git-ignored and must never be committed — obtain +# your own free license key from MinIO (https://min.io) and place it there. +# The AIStor container will not start without it. +# +# Verified empirically against RELEASE.2026-08-07T18-34-35Z: +# - MINIO_ROOT_USER / MINIO_ROOT_PASSWORD still set the root credentials +# (unchanged from community MinIO). +# - Command shape: the image entrypoint expects `minio` as its first +# argument, so `command: minio server /data --license /minio.license` +# is passed through as-is. +# - `mc ready local` works as a healthcheck (mc ships in the image; curl +# does not). +# +# 127.0.0.1 is load-bearing on both sides: aws-lite picks path-style only +# for IP/localhost hosts (stock MinIO/AIStor only speaks path-style, no +# MINIO_DOMAIN here), and the port publish below binds 127.0.0.1 only — not +# 0.0.0.0 — so this fixed-credential test instance is never reachable from +# the LAN. +# +# Procedure: # docker compose -f docker-compose.minio-test.yml up -d +# docker compose -f docker-compose.minio-test.yml ps # wait for "healthy" # cd server && TREK_TEST_S3_ENDPOINT=http://127.0.0.1:9000 \ # TREK_TEST_S3_BUCKET=trek-test TREK_TEST_S3_ACCESS_KEY_ID=trekci \ # TREK_TEST_S3_SECRET_ACCESS_KEY=trekci-secret \ # npx vitest run tests/unit/nest/storage/s3.driver.contract.test.ts -# 127.0.0.1 is load-bearing on both sides: aws-lite picks path-style only for -# IP/localhost hosts (stock MinIO only speaks path-style, no MINIO_DOMAIN -# here), and the port publish below binds 127.0.0.1 only — not 0.0.0.0 — so -# this fixed-credential test instance is never reachable from the LAN. +# docker compose -f docker-compose.minio-test.yml down -v services: minio: - # Docker Hub's minio/minio repo is archived — quay.io is the maintained - # registry going forward. Pinned tag: repo is stable/frozen upstream. - image: quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z.hotfix.7aa24e772 - command: server /data + # Docker Hub's minio/minio repo is archived, and quay.io/minio/minio (the + # former community line) receives no further updates — MinIO dropped it + # entirely. AIStor is the maintained successor; it requires a license + # (see header above). Pinned tag. + image: quay.io/minio/aistor/minio:RELEASE.2026-08-07T18-34-35Z + command: minio server /data --license /minio.license ports: - "127.0.0.1:9000:9000" + volumes: + - ./minio-licence.key:/minio.license:ro environment: - MINIO_ROOT_USER=trekci - MINIO_ROOT_PASSWORD=trekci-secret