# Runner capability probe — the instrument behind the "What a job on this # runner can actually do" table in README.md. # # Committed so the claims can be RE-DERIVED rather than taken on faith. The # README's table is a measurement with a date on it; runner upgrades, act # version bumps and gitea upgrades can all invalidate it silently. Re-run this # after any of those, or before betting a new repo's CI design on the table. # # HOW TO RUN # 1. Create a throwaway repo (a service account's own namespace is fine — # the fleet runner is registered instance-wide and picks up any repo). # 2. Commit this file to .gitea/workflows/probe.yml. Adding the file is the # trigger; there is no workflow_dispatch here on purpose, and the run-rerun # API 404s on gitea 1.26. # 3. Poll /api/v1/repos///actions/runs — NOT /actions/tasks, # which returned an empty workflow_runs for a run that /runs listed and # executed (gitea 1.26.1). # 4. Read logs at /actions/jobs//logs. # 5. DELETE the repo. It is an instrument, not a fixture. # # Last run 2026-09-02 on ana-docker-runner (label pfi-fleet): all three green. name: capability-probe on: [push] jobs: # Does a `uses:` ref resolve from OUR mirrors instead of github.com? # # This is the per-workflow half of the github-independence work, and it does # not need the DEFAULT_ACTIONS_URL=self flip that is parked on act_runner's # action-fetch auth. A bare `uses: actions/checkout@v4` goes to github at # step zero; the full URL does not. mirror-uses: runs-on: pfi-fleet # node:20-bookworm, not python:*-slim. JS actions execute as # `node /var/run/act/actions/.../dist/index.js`, so a job image without a # node binary fails on its FIRST `uses:` regardless of what the step does. # This image also carries git, which checkout needs. container: node:20-bookworm steps: - name: checkout from the local gitea mirror, not github uses: https://gitea.phasefinal.com/actions/checkout@v4 - run: echo "MIRROR_USES=ok"; git log --oneline -1 # Do `services:` containers work, and are they reachable by service name? # # The service name is the hostname. Job container is postgres:16-alpine only # so psql is already present — no apt detour; the steps are plain `run:` so # this job needs no node. service-containers: runs-on: pfi-fleet container: postgres:16-alpine services: probedb: image: postgres:16-alpine env: POSTGRES_PASSWORD: probe POSTGRES_DB: probe steps: - run: | # WAIT, do not trust startup ordering: the service answered on the # 4th attempt (~6s) in the 2026-09-02 run. A test suite that connects # immediately gets a flake that looks like a code bug. for i in $(seq 1 30); do pg_isready -h probedb -U postgres && break; sleep 2; done PGPASSWORD=probe psql -h probedb -U postgres -d probe -c 'select version();' echo "SERVICES=ok" # What does a job actually reach on the HOST daemon? # # ⚠ Expect this to succeed, and read the output as an exposure report rather # than a capability list. `container.valid_volumes: []` does not gate it — # act_runner mounts /var/run/docker.sock itself. On 2026-09-02 this printed # uid 0 and all 49 containers on ana-docker, gitea included. docker-reach: runs-on: pfi-fleet container: docker:27-cli steps: - run: | echo "--- identity ---"; id echo "--- socket ---"; ls -la /var/run/docker.sock 2>&1 || echo "NO_SOCKET" echo "--- host containers visible ---"; docker ps --format '{{.Names}}' 2>&1 | head -8 echo "--- host container count ---"; docker ps -q 2>/dev/null | wc -l echo "--- compose plugin ---"; docker compose version 2>&1 | head -2 echo "REACH_PROBE=done"