Repository navigation
211 lines (175 loc) · 8.93 KB
/
Copy pathci.yml
File metadata and controls
211 lines (175 loc) · 8.93 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
199
200
201
202
203
204
205
206
207
208
209
210
211
name: ci
# Minimal CI for the cht-ui-builder repo. The zero-SNOMED / licensing guard
# in shared/src/fhir/roundtrip.test.ts is only meaningful if it runs unattended
# (the legal exposure ships in the bundled pack on every push), so this
# workflow's job is to make sure build + test + lint run on every push and PR.
on:
push:
branches: [master]
pull_request:
jobs:
build-test-lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.2.2
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Build shared (parsers + serializers)
run: pnpm --filter @cht-ui/shared build
- name: Run shared tests (incl. zero-SNOMED + round-trip oracle)
run: pnpm --filter @cht-ui/shared test
- name: Smoke-test fhir-mapping round-trip on the committed fixture
run: node scripts/smoke-parser.mjs shared/src/fhir/__fixtures__/mch-pregnancy.fhir-mapping.json
- name: Typecheck all workspaces
run: pnpm typecheck
# Hosted, multi-user authoring (docs/plans/hosted-authoring.md §12): two
# users, per-user registry, project ids on every request, zip import /
# export, zip-slip refusal, and that user A can reach none of user B's
# project by any route. Spawns the built server in hosted AND desktop
# mode against throwaway data dirs; no python needed.
- name: Build server
run: pnpm --filter @cht-ui/server build
- name: Hosted-authoring acceptance (API level, both modes)
run: node scripts/hosted-acceptance.mjs
# NOTE: `pnpm lint` is deferred from CI pending a separate cleanup PR.
# The repo's eslint.config.js declares Node globals only for *.ts/*.tsx
# and lacks browser globals for the client/ workspace and Node globals
# for *.mjs scripts — so ~100 pre-existing `no-undef` errors gate it
# today. The Standard codes slice itself is lint-clean
# (shared/src/fhir/** has zero new errors/warnings). Re-add this step
# once the eslint config is fixed.
generated-forms-validate:
# The pyxform oracle. Nothing else we run can tell whether an XForm's
# XPaths actually resolve, and that blind spot let a deploy blocker ship:
# `insertContactFieldRef` emitted `../inputs/contact/name` without
# declaring the node, and cht-conf's `validate-app-forms` fails the ENTIRE
# run on one bad XPath — so one form blocked every form and the app
# settings. Nine green flow tests and a clean typecheck all missed it.
#
# Its own job rather than a step in build-test-lint, because it needs
# python + pyxform and takes noticeably longer than the unit suite.
# A fast hermetic version of the same invariant runs in the shared tests
# (insertContactFieldRef.declare.test.ts), so a break shows up there too.
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.2.2
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- uses: actions/setup-python@v5
with:
python-version: '3.12'
# cht-conf shells out to pyxform for convert-app-forms. Verified
# locally against pyxform 4.5.0 / cht-conf 6.5.0.
- name: Install pyxform
run: python -m pip install --upgrade pyxform
- run: pnpm install --frozen-lockfile
# The script drives the REAL generator out of shared/dist rather than
# reimplementing it, so shared has to be built first.
- name: Build shared
run: pnpm --filter @cht-ui/shared build
# Asserts both directions: a form this tool generates passes, AND a
# deliberately-broken one is rejected. Without the second check a
# validator that stopped looking would still show green.
- name: Validate tool-generated forms with cht-conf + pyxform
run: node scripts/validate-generated-forms.mjs
templates-validate:
# Every starter template must be deployable AS SHIPPED. A standing PO
# directive says each template ships minimal-valid versions of every
# cht-conf-required file, and nothing checked it: cht-default did not
# compile (its extras require moment with nothing to resolve it) until
# docs/plans/hosted-authoring.md §9 found it by hand. This copies each
# template (dotfiles included), installs its declared deps if it ships a
# package.json, and runs compile + convert + validate with the real
# cht-conf + pyxform. The same script runs inside the Dockerfile image.
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.2.2
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install pyxform
run: python -m pip install --upgrade pyxform
- run: pnpm install --frozen-lockfile
- name: Validate every template with cht-conf + pyxform
run: node scripts/validate-templates.mjs
e2e:
# Browser-driven Playwright suite against the committed mini-config fixture.
# playwright.config.ts boots a non-watch API server (server `start`) + Vite
# via its `webServer` block, so this job just needs the builds in place.
# Only the fresh-clone-safe specs run here; helper-builder.spec.ts needs a
# real cht-conf project with a contact-summary file and is excluded until
# the fixture grows one (see PR notes).
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.2.2
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
# webServer runs `server start` (node dist) + Vite (serves prebuilt
# shared/dist), so both must be built before Playwright launches them.
- name: Build shared + server
run: |
pnpm --filter @cht-ui/shared build
pnpm --filter @cht-ui/server build
- name: Install Playwright browser
run: pnpm --filter @cht-ui/client exec playwright install --with-deps chromium
- name: Run e2e (condition-builder + form-editing + fhir-mapping + form-data-passing + quick-hierarchy + contact-form-tile-classification + form-context-types + hierarchy-ux-polish + poc-build + anc-build + geriatric-blockers + pick-preexisting-values)
# anc-build-deploy runs CI-safe by default (build + on-disk assertions only);
# ANC_OUTPUT_DIR gives it a Linux-portable path, and the live deploy stays
# off (it only runs under LIVE_DEPLOY=1, which CI never sets).
# geriatric-blockers covers the choice-value dropdowns (§1) and the OR
# authoring → &&-guard round-trip (§3) against mini-config; its write
# leg copies the fixture to a temp dir first, so it's hermetic.
# pick-preexisting-values is the acceptance for
# docs/plans/pick-preexisting-context-values.md: it drives BOTH halves
# of "insert a reference to a value that already exists" through the UI
# and asserts the produced form has no dangling ../inputs ref — the
# defect that used to fail validate-app-forms for the whole project.
# It copies the fixture to a temp dir too.
env:
ANC_OUTPUT_DIR: ${{ runner.temp }}/anc-build
run: pnpm --filter @cht-ui/client exec playwright test condition-builder.spec.ts form-editing.spec.ts fhir-mapping.spec.ts form-data-passing.spec.ts quick-hierarchy.spec.ts contact-form-tile-classification.spec.ts form-context-types.spec.ts hierarchy-ux-polish.spec.ts poc-build.spec.ts anc-build-deploy.spec.ts geriatric-blockers.spec.ts pick-preexisting-values.spec.ts
# Hosted, multi-user authoring at the browser level (docs/plans/
# hosted-authoring.md §12): sign up, start blank, land in the project;
# two tabs hold two projects; another user sees nothing; sign out.
# Its own config boots the server in CHT_UI_MODE=hosted against a
# throwaway DATA_ROOT and serves the BUILT client from the same origin —
# the exact shape the Dockerfile ships — so the client must be built.
- name: Build client (served by the hosted server)
run: pnpm --filter @cht-ui/client build
- name: Run hosted-mode e2e (sign-up, start blank, two tabs, isolation)
run: pnpm --filter @cht-ui/client exec playwright test -c playwright.hosted.config.ts
- name: Upload Playwright report on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: client/playwright-report/
retention-days: 7