-
Notifications
You must be signed in to change notification settings - Fork 78
133 lines (116 loc) · 4.95 KB
/
Copy pathfrontend-e2e.yml
File metadata and controls
133 lines (116 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
name: frontend-e2e
# Runs only when a PR carries the `ui` label. Adds a browser test layer for
# UI changes; gated to avoid spending ~5 min of CI on every backend PR.
# Trigger manually by adding the `ui` label to a PR.
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
e2e:
if: contains(github.event.pull_request.labels.*.name, 'ui')
runs-on: ubuntu-latest
timeout-minutes: 25
defaults:
run:
working-directory: src/frontend
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: src/frontend/package-lock.json
- name: Install npm dependencies
run: npm ci
- name: Cache Playwright browsers
uses: actions/cache@v5
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('src/frontend/package-lock.json') }}
- name: Install Playwright browser
run: npx playwright install --with-deps chromium
- name: Generate CI admin password
# I-01 fix (cso-diff-2026-05-17): replace the previous hardcoded
# `CiTestPassword!1` fallback with a per-run random value so the
# repo never publishes a default admin credential, even one only
# reachable from the runner sandbox. Honours an explicit
# E2E_ADMIN_PASSWORD secret override when set. The literal `Aa1!`
# suffix guarantees OWASP ASVS 2.1 complexity classes on the
# random branch (upper / lower / digit / special) — `tr -d`
# strips base64 chars that would break form-encoded curl bodies
# later.
env:
OVERRIDE: ${{ secrets.E2E_ADMIN_PASSWORD }}
run: |
set -euo pipefail
if [ -n "${OVERRIDE:-}" ]; then
PASS="$OVERRIDE"
else
PASS="$(openssl rand -base64 24 | tr -d '/+=\n')Aa1!"
fi
echo "::add-mask::$PASS"
echo "ADMIN_PASSWORD=$PASS" >> "$GITHUB_ENV"
- name: Start Trinity stack
working-directory: ${{ github.workspace }}
env:
# ADMIN_PASSWORD is inherited from GITHUB_ENV (see the
# "Generate CI admin password" step above).
ANTHROPIC_API_KEY: ${{ secrets.E2E_ANTHROPIC_API_KEY || 'placeholder' }}
run: |
# Generate the minimum .env needed to boot. Real secrets are not
# required for e2e — login uses ADMIN_PASSWORD only.
cp .env.example .env
echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env
echo "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" >> .env
echo "SECRET_KEY=$(openssl rand -hex 32)" >> .env
./scripts/deploy/start.sh
- name: Wait for backend health
run: |
for i in {1..60}; do
if curl -fsS http://localhost:8000/health >/dev/null 2>&1; then
echo "backend healthy"; exit 0
fi
sleep 2
done
echo "backend never became healthy"; exit 1
# Issue #874 regression guards (`verify-non-root`,
# `verify-prod-frontend-uid`) moved to .github/workflows/container-security.yml
# so they run unconditionally on infrastructure PRs (this workflow
# is `ui`-label gated and would otherwise skip them on backend PRs).
- name: Skip first-time setup wizard
working-directory: ${{ github.workspace }}
run: |
# On a fresh DB the admin user is bootstrapped from ADMIN_PASSWORD,
# but `setup_completed` stays false (the backfill migration runs
# before admin creation). Without this flag the frontend redirects
# every route to /setup. Mark setup complete directly.
docker exec trinity-backend python3 -c "from database import db; db.set_setting('setup_completed', 'true'); print('setup_completed=true')"
- name: Run Playwright smoke tests
env:
# ADMIN_PASSWORD is inherited from GITHUB_ENV (see the "Generate
# CI admin password" step).
E2E_BASE_URL: http://localhost
# Only @smoke-tagged specs run in CI. @visual / @interactive specs
# are local-only until their flake/baseline story is sorted (#596).
run: npm run test:e2e:smoke
- name: Collect Trinity logs on failure
if: failure()
working-directory: ${{ github.workspace }}
run: |
docker compose logs --no-color --tail=200 backend frontend mcp-server > trinity-logs.txt || true
- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v7
with:
name: playwright-report
path: src/frontend/e2e/playwright-report/
retention-days: 14
- name: Upload failure artifacts
if: failure()
uses: actions/upload-artifact@v7
with:
name: e2e-failure-artifacts
path: |
src/frontend/e2e/test-results/
trinity-logs.txt
retention-days: 14