ci(forgejo): adapt e2e + image-smoke to isolated per-job DinD runners
Some checks failed
CI / Dockerfile Package Check (push) Successful in 2m52s
CI / Security Scan (push) Successful in 7m17s
CI / OpenSpec Validate (push) Successful in 4m24s
CI / Typecheck (push) Successful in 4m5s
CI / Lint (push) Successful in 5m44s
CI / Build (push) Successful in 2m17s
CI / Unit Tests (push) Failing after 4m11s
CI / Journal Image Smoke Test (push) Failing after 4m59s
CI / Visual Tests (push) Successful in 11m24s
CI / E2E Tests (push) Failing after 7m59s

Runners migrated to 2 isolated runner+dind pairs (capacity 1 each): each job
gets its own docker daemon (job-to-job isolation; host daemon untouched).
- e2e: seed BRouter segment into the compose volume via a DinD container
  (no cross-daemon bind mount); services addressed at host.docker.internal;
  compose project pinned to 'trails'.
- image-smoke: db:push reaches postgres at host.docker.internal; the
  --network-host journal container uses localhost; health-check via
  host.docker.internal.
DOCKER_HOST is also injected globally via the runner's config (runner.envs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ullrich Schäfer 2026-07-22 20:33:43 +02:00
parent 805ac86935
commit 159d3f3348
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9

View file

@ -196,9 +196,9 @@ jobs:
needs: build
runs-on: ubuntu-latest
env:
DATABASE_URL: postgres://trails:trails@localhost:5432/trails
# The DinD daemon lives at this address on the runner network; the job
# container needs it explicitly (it has no /var/run/docker.sock).
# Services run on the DinD daemon; from the job container their published
# ports are reachable at host.docker.internal (not localhost).
DATABASE_URL: postgres://trails:trails@host.docker.internal:5432/trails
DOCKER_HOST: tcp://host.docker.internal:2375
steps:
- uses: actions/checkout@v7
@ -209,36 +209,25 @@ jobs:
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Cache BRouter segment
id: segment-cache
uses: actions/cache@v6
with:
path: /tmp/brouter-segments
key: brouter-segment-E10_N50-v1.7.9
- name: Download Berlin segment
if: steps.segment-cache.outputs.cache-hit != 'true'
run: |
mkdir -p /tmp/brouter-segments
wget -q "https://brouter.de/brouter/segments4/E10_N50.rd5" -O /tmp/brouter-segments/E10_N50.rd5
- name: Pre-seed BRouter segment volume
- name: Seed BRouter segment volume
# Download the segment directly into the compose volume via a DinD
# container — a job-side download + bind mount would not be visible to
# the DinD daemon (separate filesystem). Project name pinned to `trails`
# so the volume matches docker-compose.dev.yml's `brouter_segments`.
run: |
docker volume create trails_brouter_segments
docker run --rm \
-v /tmp/brouter-segments:/src:ro \
-v trails_brouter_segments:/dst \
alpine sh -c "cp /src/*.rd5 /dst/ && chmod a+r /dst/*.rd5"
docker run --rm -v trails_brouter_segments:/dst alpine sh -c \
"wget -q https://brouter.de/brouter/segments4/E10_N50.rd5 -O /dst/E10_N50.rd5 && chmod a+r /dst/*.rd5"
- name: Start services
run: docker compose -f docker-compose.dev.yml up -d --wait --build
run: docker compose -p trails -f docker-compose.dev.yml up -d --wait --build postgres brouter
env:
BROUTER_URL: http://localhost:17777
BROUTER_URL: http://host.docker.internal:17777
- name: Wait for BRouter routing
run: |
for i in $(seq 1 60); do
curl -s 'http://localhost:17777/brouter?lonlats=13.4,52.5|13.5,52.5&profile=trekking&format=geojson' 2>/dev/null | grep -q "FeatureCollection" && echo "BRouter ready" && break
curl -s 'http://host.docker.internal:17777/brouter?lonlats=13.4,52.5|13.5,52.5&profile=trekking&format=geojson' 2>/dev/null | grep -q "FeatureCollection" && echo "BRouter ready" && break
[ "$i" = "60" ] && echo "BRouter not ready after 120s" && exit 1
sleep 2
done
@ -280,7 +269,7 @@ jobs:
- name: Run E2E tests
run: pnpm test:e2e
env:
BROUTER_URL: http://localhost:17777
BROUTER_URL: http://host.docker.internal:17777
E2E: "true"
INTEGRATION_SECRET: ${{ secrets.INTEGRATION_SECRET }}
@ -339,7 +328,8 @@ jobs:
--health-timeout 5s
--health-retries 20
env:
DATABASE_URL: postgres://trails:trails@localhost:5432/trails
# From the job container the postgres service is at host.docker.internal.
DATABASE_URL: postgres://trails:trails@host.docker.internal:5432/trails
DOCKER_HOST: tcp://host.docker.internal:2375
steps:
- uses: actions/checkout@v7
@ -358,13 +348,15 @@ jobs:
- name: Boot image and wait for healthy
run: |
# Journal runs --network host on the DinD daemon, so it reaches the
# postgres service (published on DinD) at localhost:5432.
docker run -d --name journal-smoke --network host \
-e NODE_ENV=production -e E2E=true \
-e DATABASE_URL="$DATABASE_URL" \
-e DATABASE_URL="postgres://trails:trails@localhost:5432/trails" \
journal-smoke
code=000
for i in $(seq 1 30); do
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 3 http://localhost:3000/api/health || echo 000)
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 3 http://host.docker.internal:3000/api/health || echo 000)
echo "attempt $i: /api/health -> $code"
[ "$code" = "200" ] && break
if [ "$(docker inspect -f '{{.State.Running}}' journal-smoke 2>/dev/null)" != "true" ]; then