-
Notifications
You must be signed in to change notification settings - Fork 1
161 lines (132 loc) · 5.62 KB
/
Copy pathci.yml
File metadata and controls
161 lines (132 loc) · 5.62 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
# Source of truth for the checks lefthook.yml mirrors locally. Keep the
# two in sync whenever a step here changes.
name: CI
on:
push:
branches:
- master
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
verify:
# macOS, not Linux. Tutor ships as a notarized macOS DMG and parts of the
# product are deliberately macOS only. server/services/audiobook-installer.ts
# throws "Automatic ffmpeg install not yet supported on linux", and its tests
# assert the macOS install paths and download sizes, so a Linux runner fails
# on correct code. Running CI on the platform the app actually targets keeps
# the suite honest instead of weakening those assertions.
runs-on: macos-14
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm typecheck
- run: pnpm lint
- run: pnpm test
- run: pnpm knip
- run: pnpm tsx scripts/check-doc-paths.ts
# scripts/find-unnamed-buttons.mts lands via a sibling task. Guarded so
# this step is a no-op until that branch merges, rather than failing
# every run in the meantime.
- name: Check for unnamed accessible buttons (client)
run: |
if [ -f scripts/find-unnamed-buttons.mts ]; then
pnpm tsx scripts/find-unnamed-buttons.mts client
else
echo "scripts/find-unnamed-buttons.mts not present yet (lands via a sibling task) — skipping."
fi
# docs/api-routes.md is generated from the Fastify route registry, so it
# can only be wrong if someone changed a route and did not regenerate it.
# This step is what makes that impossible to merge. It runs last because
# it boots the server, and a failure here is a stale file rather than
# broken code.
- name: Check the generated API routes doc is current
run: |
pnpm docs:routes
git diff --exit-code docs/api-routes.md || {
echo "::error file=docs/api-routes.md::docs/api-routes.md is stale. Run 'pnpm docs:routes' and commit the result."
exit 1
}
# The end-to-end journey suite, in its own job so it runs alongside verify
# rather than behind it. `pnpm test` stays the fast one and never waits on a
# browser. See e2e/README.md for what the journeys cover and why the server
# is faked at its edges rather than mocked at its HTTP boundary.
e2e-web:
runs-on: macos-14
env:
# The web project never launches Electron, so the binary is dead weight
# here. The e2e-electron job below deliberately omits this.
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/Library/Caches/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-playwright-
- run: pnpm exec playwright install chromium
# No separate build step. e2e/global-setup.ts runs `vite build` itself,
# so there is exactly one code path and no way for a job to run the
# journeys against a bundle it did not build.
- run: pnpm e2e --project=web
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report-web
path: playwright-report/
retention-days: 7
# Isolated from e2e-web because it launches a real GUI application and needs
# the Electron binary, which is the one thing every other job skips
# downloading. One `--project` flag keeps it out of the web suite.
e2e-electron:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- name: Cache Electron binary
uses: actions/cache@v4
with:
path: ~/Library/Caches/electron
key: ${{ runner.os }}-electron-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-electron-
- run: pnpm install --frozen-lockfile
# The other two jobs set ELECTRON_SKIP_BINARY_DOWNLOAD, and all three
# share one pnpm store cache keyed on the lockfile, so whichever of them
# saves that cache first can hand this job an electron package whose
# postinstall was skipped and whose binary is therefore missing. The
# symptom is "Electron failed to install correctly" out of
# electron.launch, and because it depends on which parallel job wins the
# cache write, it appears as flake rather than as a broken job.
#
# install.js is the package's own postinstall. It checks the installed
# version first and downloads only what is missing, reusing the binary
# cache restored above, so running it here is idempotent and costs
# nothing when the store cache was clean.
- name: Repair the Electron binary if the shared store cache skipped it
run: node node_modules/electron/install.js
- run: pnpm e2e --project=electron
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report-electron
path: playwright-report/
retention-days: 7