From 7257fc3c0cd797b87e3f16f828f1e8e0d743ee61 Mon Sep 17 00:00:00 2001 From: ducoterra Date: Sun, 1 Nov 2026 18:07:00 -0500 Subject: [PATCH] ci: run the suite where the runner can actually start it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run #1 died in Checkout, before a single command of ours ran: actions/checkout is a JavaScript action, and the job's `container: python:3.13-slim` has no Node runtime for it. The same actions succeed on this instance with no `container:` key at all (Experimental/brain-of-reese run 264 is the proof), so the job stays on the runner and shells into the interpreter it needs instead. The suite now runs inside a pinned python:3.13-slim via whichever of podman or docker the runner has — the same runtime the publish job builds with, which is why "no runtime found" is a hard failure rather than a quiet fallback to whatever python the runner image happens to ship. Falling back there would make the gate depend on an interpreter nobody chose. 3.13 rather than the 3.14 of the dev venv: it is the floor declared in pyproject's requires-python, so CI checks the floor. The image-build smoke step lost its apt-get install podman for the same reason. LLM-Generated: true --- .gitea/workflows/build-and-push.yml | 60 ++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml index bbe8e94..c6f998b 100644 --- a/.gitea/workflows/build-and-push.yml +++ b/.gitea/workflows/build-and-push.yml @@ -13,41 +13,63 @@ jobs: # leaves :main on the last good build, which is what `podman auto-update` # keeps serving on reeseapps-mirror — so red means "nothing shipped", not # "production is broken". + # + # The suite runs *inside* a pinned python:3.13-slim container rather than via a + # `container:` job key. That is not stylistic: actions/checkout is a JavaScript + # action and a python image has no Node runtime, so run #1 died in Checkout + # before running a single command. The runner itself has both (it is where + # build-push-action builds images), so the job stays on the runner and shells + # into the container it needs. + # + # 3.13 is deliberate: it is the floor declared in pyproject's requires-python, + # so CI verifies the floor while development happens on 3.14. test: runs-on: ubuntu-latest - container: - image: python:3.13-slim steps: - name: Checkout uses: actions/checkout@v4 - - name: Install the package and the test tooling + - name: Locate the container runtime + id: runtime run: | - pip install --no-cache-dir --upgrade pip - pip install --no-cache-dir -e . - pip install --no-cache-dir \ - pytest pytest-asyncio pytest-cov pytest-timeout httpx ruff - - - name: Lint - run: | - ruff check . - ruff format --check . + set -euo pipefail + runtime="$(command -v podman || command -v docker || true)" + if [ -z "$runtime" ]; then + echo "Neither podman nor docker is on this runner, so this job cannot" + echo "run the suite in a pinned interpreter. Fix here rather than" + echo "falling back to whatever python the runner image happens to ship." + exit 1 + fi + echo "path=$runtime" >> "$GITHUB_OUTPUT" + echo "using $runtime" # Unit + API only. tests/e2e drives a real Chromium through capture -> # encode -> SRTP -> decode and needs a browser install and, for the # realdisplay rung, an X server; both stay local gates (see AGENTS.md). # --ignore keeps them out of collection entirely: -m filtering happens # after import, and tests/e2e/conftest.py imports playwright. - - name: Test - run: pytest -q --no-cov --ignore=tests/e2e + - name: Lint and test + run: | + set -euo pipefail + "${{ steps.runtime.outputs.path }}" run --rm \ + -v "$GITHUB_WORKSPACE:/src" -w /src \ + docker.io/library/python:3.13-slim \ + /bin/bash -euo pipefail -c ' + pip install --no-cache-dir -q . + pip install --no-cache-dir -q \ + pytest pytest-asyncio pytest-cov pytest-timeout httpx ruff + ruff check . + ruff format --check . + pytest -q --no-cov --ignore=tests/e2e + ' - name: Smoke the image build - # Catches a broken Containerfile (a missing COPY source, a bad uv - # install) here rather than in the publish job below. + # Catches a broken Containerfile (a missing COPY source, a failing uv + # install step) here rather than in the publish job below. run: | - apt-get update -qq && apt-get install -y -qq --no-install-recommends podman - podman build -t mirror:ci . - podman run --rm mirror:ci --help >/dev/null + set -euo pipefail + "${{ steps.runtime.outputs.path }}" build -t mirror:ci . + "${{ steps.runtime.outputs.path }}" run --rm mirror:ci --help >/dev/null build-and-push-app: needs: test