ci: run the suite where the runner can actually start it
Build and Push Containers / test (push) Failing after 40s
Build and Push Containers / build-and-push-app (push) Skipped

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
This commit is contained in:
2026-11-01 18:07:00 -05:00
parent 2e79430ac7
commit 7257fc3c0c
+41 -19
View File
@@ -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