-
Notifications
You must be signed in to change notification settings - Fork 1
174 lines (162 loc) · 6.72 KB
/
Copy pathprod-e2e.yml
File metadata and controls
174 lines (162 loc) · 6.72 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
name: prod-e2e
# Run the Playwright e2e suite against the production URL after every
# production deploy. Sandbox deploys are exercised by humans and tested
# by the PR-preview e2e job on each PR before merge — this workflow is
# purely the post-prod regression guard.
#
# If e2e fails, file a GitHub issue tagged `prod-e2e-fail` so the
# regression isn't silent — production failures can otherwise sit
# undetected for days.
on:
workflow_run:
workflows: ['deploy-ui']
types: [completed]
branches: [main]
workflow_dispatch:
permissions:
contents: read
issues: write
actions: read
jobs:
resolve-target:
if: github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main')
runs-on: ubuntu-latest
outputs:
target: ${{ steps.read.outputs.target }}
steps:
- name: Download deploy target artifact (workflow_run path)
if: github.event_name == 'workflow_run'
uses: actions/download-artifact@v4
with:
name: deploy-target
path: deploy-meta
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true
- name: Read deploy target
id: read
run: |
# workflow_dispatch runs are always treated as production —
# the operator triggered this on purpose to re-run prod
# regression. workflow_run runs read the artifact written by
# deploy-ui (sandbox vs production). If the artifact is
# missing (e.g. older deploy-ui run that pre-dates this
# change), default to skipping rather than testing the wrong
# URL.
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
target=production
elif [ -f deploy-meta/target.txt ]; then
target=$(tr -d '[:space:]' < deploy-meta/target.txt)
else
target=skip
fi
echo "target=$target" >> "$GITHUB_OUTPUT"
echo "Resolved target: $target"
e2e:
needs: resolve-target
if: needs.resolve-target.outputs.target == 'production'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
fetch-depth: 1
- name: Set up Node 20 + pnpm
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Enable pnpm
run: npm install --global pnpm@10
- name: Install site deps
working-directory: site
run: pnpm install --frozen-lockfile
- name: Install Playwright browsers
working-directory: site
run: pnpm exec playwright install chromium --with-deps
- name: Wait for production deploy to be live
run: |
# gh-pages CDN propagation lags the deploy workflow.
URL="https://abstractatlas.brainkb.org/ohbm2026/"
echo "Probing $URL"
for i in $(seq 1 30); do
code=$(curl -s -o /dev/null -w '%{http_code}' "$URL" || true)
if [ "$code" = "200" ]; then
echo "Prod live after ${i} polls."
break
fi
echo " [$i/30] HTTP $code — sleeping 10s"
sleep 10
done
- name: Run Playwright e2e against production
id: e2e
working-directory: site
env:
# `PLAYWRIGHT_BASE_URL` terminates at the conference home so
# specs that use relative paths (`./about/`, `./abstract/...`)
# don't accidentally land on the root redirect island.
PLAYWRIGHT_BASE_URL: https://abstractatlas.brainkb.org/ohbm2026/
UI_DATA_AVAILABLE: '1'
run: pnpm exec playwright test --project=chromium
- name: Upload Playwright report on failure
if: failure()
uses: actions/upload-artifact@v4
id: report
with:
name: playwright-report-prod-${{ github.run_id }}
path: site/playwright-report/
retention-days: 30
- name: File issue on prod e2e failure
if: failure()
uses: actions/github-script@v7
env:
REPORT_NAME: playwright-report-prod-${{ github.run_id }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
DEPLOY_SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
with:
script: |
const runUrl = process.env.RUN_URL;
const deploySha = (process.env.DEPLOY_SHA || '').slice(0, 7);
const title = `prod e2e regression on ${deploySha}`;
const body = [
`Playwright e2e suite failed against production after the latest main-branch deploy.`,
``,
`**Workflow run:** ${runUrl}`,
`**Deploy SHA:** \`${process.env.DEPLOY_SHA}\``,
`**Production URL:** https://abstractatlas.brainkb.org/ohbm2026/`,
``,
`The Playwright report is attached as the \`${process.env.REPORT_NAME}\` artifact on the workflow run (30-day retention).`,
``,
`Triage:`,
`1. Open the workflow run, download the report artifact, and inspect the failed traces.`,
`2. Determine whether the failure reflects a real regression or an environmental flake (CDN, Dropbox 5xx, etc.).`,
`3. If real: open a fix PR. If transient: close this issue with the rationale recorded.`,
].join('\n');
// De-dupe: if there's already an open `prod-e2e-fail` issue
// for the same SHA, comment instead of opening a duplicate.
const { data: existing } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'prod-e2e-fail',
state: 'open',
per_page: 50,
});
const dup = existing.find((iss) => iss.title.endsWith(deploySha));
if (dup) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: dup.number,
body: `Another failed run on the same deploy SHA: ${runUrl}`,
});
core.info(`Commented on existing issue #${dup.number}`);
return;
}
const { data: issue } = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body,
labels: ['prod-e2e-fail', 'priority:high'],
});
core.info(`Filed issue #${issue.number}: ${issue.html_url}`);