services: # Seed a deterministic bootstrap token for first-run setup E2E flows. # This is only used by the test stack and is safe to keep deterministic. seed-bootstrap-token: image: alpine:3.24@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b container_name: ${PULSE_E2E_SEED_CONTAINER:-pulse-test-seed-bootstrap-token} environment: - PULSE_E2E_BOOTSTRAP_TOKEN=${PULSE_E2E_BOOTSTRAP_TOKEN:-0123456789abcdef0123456789abcdef0123456789abcdef} - PUID=${PUID:-1000} - PGID=${PGID:-1000} volumes: - test-data:/data command: - sh - -c - | set -e umask 077 : "$${PULSE_E2E_BOOTSTRAP_TOKEN:?PULSE_E2E_BOOTSTRAP_TOKEN is required}" token="$${PULSE_E2E_BOOTSTRAP_TOKEN}" if [ "$${#token}" -ne 48 ]; then echo "PULSE_E2E_BOOTSTRAP_TOKEN must be a 48-character hex token" >&2 exit 1 fi case "$${token}" in *[!0123456789abcdefABCDEF]*) echo "PULSE_E2E_BOOTSTRAP_TOKEN must be a 48-character hex token" >&2 exit 1 ;; esac printf '%s\n' "$${token}" > /data/.bootstrap_token chown "$${PUID:-1000}:$${PGID:-1000}" /data /data/.bootstrap_token chmod 700 /data chmod 600 /data/.bootstrap_token networks: - test-network # Mock GitHub API server for controlled testing mock-github: image: ${PULSE_E2E_MOCK_IMAGE:-pulse-mock-github:test} container_name: ${PULSE_E2E_MOCK_CONTAINER:-pulse-mock-github} ports: - "127.0.0.1:${PULSE_E2E_MOCK_GITHUB_PORT:-8080}:8080" environment: - PORT=8080 - MOCK_BASE_URL=http://mock-github:8080 # Control test scenarios via environment variables - MOCK_CHECKSUM_ERROR=${MOCK_CHECKSUM_ERROR:-false} - MOCK_NETWORK_ERROR=${MOCK_NETWORK_ERROR:-false} - MOCK_RATE_LIMIT=${MOCK_RATE_LIMIT:-false} - MOCK_STALE_RELEASE=${MOCK_STALE_RELEASE:-false} healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"] interval: 5s timeout: 3s retries: 3 start_period: 5s networks: - test-network # Pulse server under test pulse-test: image: ${PULSE_E2E_SERVER_IMAGE:-pulse:test} container_name: ${PULSE_E2E_SERVER_CONTAINER:-pulse-test-server} ports: - "127.0.0.1:${PULSE_E2E_PORT:-7655}:7655" - "127.0.0.1:${PULSE_E2E_AGENT_PORT:-7656}:7656" environment: - TZ=UTC # Dedicated agent-ingest listener so E2E can prove the split-port # isolation contract (only /api/agents/* served on this port). - PULSE_AGENT_INGEST_PORT=7656 # Point to mock GitHub server - PULSE_UPDATE_SERVER=http://mock-github:8080 # Use /data which is already owned by pulse user via entrypoint - PULSE_DATA_DIR=/data # Enable debug logging - PULSE_LOG_LEVEL=debug # Mock mode is the default shared-estate contract. Dedicated lifecycle # jobs can disable it without maintaining a second compose definition. - PULSE_MOCK_MODE=${PULSE_MOCK_MODE:-true} # Seven days is the deepest live-history window exercised by Core E2E. # Keep the harness seed proportional to that contract instead of making # every parallel shard build the production-preview 90-day timeline. - PULSE_MOCK_TRENDS_SEED_DURATION=${PULSE_MOCK_TRENDS_SEED_DURATION:-168h} # Dev-only endpoints the suite depends on (first-run reset in the # first-session specs) are gated on development mode. - PULSE_DEV=true # Each shard's isolated browser sessions share one Docker bridge IP. # Keep production's universal limit intact while preventing that synthetic # aggregation from starving later tests in this development-only stack. - PULSE_DEV_GENERAL_API_RATE_LIMIT=5000 - PULSE_MULTI_TENANT_ENABLED=${PULSE_MULTI_TENANT_ENABLED:-false} - PULSE_ALLOW_DOCKER_UPDATES=true - PULSE_UPDATE_STAGE_DELAY_MS=250 - PUID=${PUID:-1000} - PGID=${PGID:-1000} volumes: - test-data:/data extra_hosts: # Lets webhook E2E point Pulse at a capture listener on the test host. - "host.docker.internal:host-gateway" depends_on: seed-bootstrap-token: condition: service_completed_successfully mock-github: condition: service_healthy healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:7655/api/health"] interval: 5s timeout: 3s retries: 5 start_period: 10s networks: - test-network volumes: test-data: driver: local networks: test-network: driver: bridge