Files
rfc-app/testing/docker-compose.yml
Ben Stull 2fc7029bd9 test(e2e): §22-current Tier-1 harness + metadata E2E (SLICE-3/4/5)
Modernize the Tier-1 stack to the three-tier app and add browser coverage for
the §22.4a metadata UI, closing the E2E gap deferred across SLICE-3/4/5:
- seed-gitea.sh: create a REGISTRY_REPO with projects.yaml + a faceted named
  collection (.collection.yaml fields: priority enum + tags) seeded with three
  metadata-bearing entries; register content+registry webhooks; self-guarding
  (skip if a prior token still works) so a dependency-triggered re-run can't
  remint and invalidate the backend's token.
- .env.tier1: REGISTRY_REPO/DEFAULT_PROJECT_ID; disable OTC cooldown + lift the
  per-IP auth limiter for the single-IP test runner.
- docker-compose: pin backend image; backend-seed inserts a granted owner the
  OTC path can sign in as (write paths need contributor+).
- Makefile: two-phase tier1-up (seed to completion, then create backend so it
  reads the populated token env); robust down; e2e-fresh = down+up+e2e (the
  canonical run, since the edit/bulk specs mutate the seeded corpus).
- metadata.spec.js: SLICE-3 faceted filter (anon), SLICE-4 edit panel (owner),
  SLICE-5 bulk bar (owner). 4 passed against a fresh stack.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 22:29:11 -07:00

120 lines
3.4 KiB
YAML

name: rfc-tier1
services:
gitea:
image: gitea/gitea:1.22
environment:
GITEA__security__INSTALL_LOCK: "true"
GITEA__server__ROOT_URL: "http://gitea:3000/"
GITEA__server__HTTP_PORT: "3000"
GITEA__database__DB_TYPE: "sqlite3"
GITEA__webhook__ALLOWED_HOST_LIST: "*"
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:3000/api/healthz"]
interval: 5s
timeout: 3s
retries: 30
ports:
- "3001:3000"
gitea-admin-init:
image: gitea/gitea:1.22
# The gitea CLI refuses to run as root (loadRunModeFrom [F] "not
# supposed to be run as root"). Our custom entrypoint bypasses the
# image's s6 init that normally drops to the git user, so set it here.
user: git
depends_on:
gitea:
condition: service_healthy
volumes_from:
- gitea
entrypoint: ["/bin/sh", "-c"]
command:
- >
gitea admin user create --admin --username giteaadmin
--password giteaadmin-pass --email admin@example.test
--must-change-password=false || true
restart: "no"
gitea-seed:
image: alpine:3.20
depends_on:
gitea-admin-init:
condition: service_completed_successfully
env_file:
- .env.tier1
environment:
GITEA_ADMIN_USER: giteaadmin
GITEA_ADMIN_PASSWORD: giteaadmin-pass
GITEA_BOT_PASSWORD: rfc-bot-pass
SEED_OUT: /seed/.env.tier1.generated
volumes:
- ./seed-gitea.sh:/seed-gitea.sh:ro
- ./generated:/seed
entrypoint: ["/bin/sh", "-c"]
command:
- apk add --no-cache curl >/dev/null && sh /seed-gitea.sh
restart: "no"
backend:
image: rfc-tier1-backend
build:
context: ..
dockerfile: testing/backend.Dockerfile
depends_on:
gitea-seed:
condition: service_completed_successfully
env_file:
- .env.tier1
- ./generated/.env.tier1.generated
volumes:
- backend-data:/data
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/api/health').status==200 else 1)"]
interval: 5s
timeout: 3s
retries: 30
# Insert a granted deployment-owner user keyed by a known e2e email, so the
# OTC sign-in path (which provisions only `pending` contributors) yields an
# owner who can exercise the metadata edit/bulk write paths (SLICE-4/5). The
# owner identity (gitea_login='owner') matches OWNER_GITEA_LOGIN. Idempotent.
backend-seed:
image: rfc-tier1-backend
depends_on:
backend:
condition: service_healthy
volumes:
- backend-data:/data
entrypoint: ["python", "-c"]
command:
- |
import sqlite3
c = sqlite3.connect("/data/rfc-app.db")
c.execute("""INSERT INTO users
(gitea_id, gitea_login, email, display_name, avatar_url, role, permission_state)
SELECT 9001, 'owner', 'e2e-owner@example.test', 'E2E Owner', '', 'owner', 'granted'
WHERE NOT EXISTS (SELECT 1 FROM users WHERE email='e2e-owner@example.test' COLLATE NOCASE)""")
c.commit(); c.close()
print("backend-seed: owner user ready")
restart: "no"
web:
build:
context: ..
dockerfile: testing/web.Dockerfile
depends_on:
backend:
condition: service_healthy
ports:
- "8080:80"
mailpit:
image: axllent/mailpit:latest
ports:
- "8025:8025"
- "1025:1025"
volumes:
backend-data: