-
Notifications
You must be signed in to change notification settings - Fork 10
198 lines (174 loc) · 7.33 KB
/
Copy pathci.yml
File metadata and controls
198 lines (174 loc) · 7.33 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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: CI
on:
pull_request:
# A queued pull request is tested on a temporary gh-readonly-queue ref, which
# fires neither pull_request nor push. Without this the merge queue waits on
# checks that never start.
merge_group:
push:
branches:
- main
# Cancel superseded runs on the same PR/branch. Merge group runs fall through to
# github.ref, which is unique per queue entry, and are never cancelled —
# cancelling one drops its pull request out of the queue.
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run typecheck
lint:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm test
# End-to-end smoke tests against a production build. Not yet a required
# check — continue-on-error keeps failures visible without blocking merges
# while the suite is still being built out.
e2e:
name: e2e (non-blocking)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run test:e2e
- name: Upload playwright report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: playwright-report
path: playwright-report/
retention-days: 14
# public/llms.txt, llms-full.txt, and AGENTS.md are generated from the route
# tree and committed. They go stale whenever a route is added, renamed, or
# removed, so this fails if they differ from a fresh generation (it also
# reports sitemap drift). Fix with: npm run llms && npm run agents
docs:
name: docs (generated agent index)
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run docs:check
public-build-excludes-internal:
name: public build excludes internal-only surfaces
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24
cache: npm
- run: npm ci
# The default (external) build is what ships to Vercel. Deliberately no
# NEXT_PUBLIC_DEPLOY_TARGET here, so this reproduces the public build.
- run: npm run build
# Guards the deployment matrix in deploy.config.mjs: a surface that is not
# shipped to the external target must be unreachable on the public site.
# Without this, dropping the middleware rule — or adding an internal-only
# page and forgetting its SURFACES entry — would silently publish it.
- name: Assert internal-only surfaces are absent
run: |
set -euo pipefail
npx next start -p 3000 &
SERVER_PID=$!
trap 'kill $SERVER_PID 2>/dev/null || true' EXIT
for i in $(seq 1 60); do
if curl -fsS -o /dev/null http://localhost:3000/; then break; fi
if [ "$i" -eq 60 ]; then echo "server never became ready"; exit 1; fi
sleep 1
done
fail=0
# Internal-only routes must 404 on the public build. Include the
# legacy /tips prefixes so old URLs stay absent too.
for route in /internal-explorer /internal-explorer/block/0x1 \
/internal-explorer/bundles/0x1 /api/internal-explorer/blocks \
/tips /tips/block/0x1 /tips/bundles/0x1 /api/tips/blocks \
/benchmark /benchmark/run/latest /benchmark/run-comparison/1 \
/benchmark/load-tests/sepolia; do
code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:3000${route}")
if [ "${code}" != "404" ]; then
echo "FAIL: ${route} returned ${code}, expected 404"
fail=1
fi
done
# Pages that must stay public.
for route in / /snapshots; do
code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:3000${route}")
if [ "${code}" != "200" ]; then
echo "FAIL: ${route} returned ${code}, expected 200"
fail=1
fi
done
# No nav link to, or sitemap entry for, an internal-only section.
for section in /internal-explorer /tips /benchmark; do
if curl -s http://localhost:3000/ | grep -q "href=\"${section}\""; then
echo "FAIL: public homepage links to ${section}"
fail=1
fi
if curl -s http://localhost:3000/sitemap.xml | grep -q "${section}"; then
echo "FAIL: public sitemap lists ${section}"
fail=1
fi
done
if [ "${fail}" -ne 0 ]; then exit 1; fi
echo "OK: internal-only surfaces are absent from the public build"