Skip to content

Commit 6e7d852

Browse files
Add website with API docs, XML doc examples, and CI optimization (#12)
# TLDR; Website + API docs with unified CSS, XML doc examples, CI path filtering # Brief Details - Eleventy website with same CSS as main site (no separate DocFX styling) - API docs generated from C# XML comments with clickable type links - XML doc examples added to SchemaBuilder, SchemaDiff, SyncState, DbConnectionExtensions - CI only runs tests when relevant code changes (dorny/paths-filter) # How Do The Tests Prove This Works? - `npm run build` in Website/ succeeds - Generated API docs render with site CSS at /apidocs/ - Type links navigate to correct pages (e.g., SyncError → /apidocs/Sync/SyncError/) - CI skips test jobs when only Website files change 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 360afd4 commit 6e7d852

64 files changed

Lines changed: 5740 additions & 41 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 257 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,24 @@ name: CI
33
on:
44
push:
55
branches: [main]
6+
paths:
7+
- '**/*.cs'
8+
- '**/*.csproj'
9+
- '**/*.sln'
10+
- '**/Directory.Build.props'
11+
- '**/Directory.Packages.props'
12+
- '.github/workflows/ci.yml'
13+
- '.config/dotnet-tools.json'
614
pull_request:
715
branches: [main]
16+
paths:
17+
- '**/*.cs'
18+
- '**/*.csproj'
19+
- '**/*.sln'
20+
- '**/Directory.Build.props'
21+
- '**/Directory.Packages.props'
22+
- '.github/workflows/ci.yml'
23+
- '.config/dotnet-tools.json'
824
workflow_dispatch:
925

1026
env:
@@ -13,6 +29,68 @@ env:
1329
DOTNET_CLI_TELEMETRY_OPTOUT: true
1430

1531
jobs:
32+
# Detect which areas changed to conditionally run tests
33+
changes:
34+
name: Detect Changes
35+
runs-on: ubuntu-latest
36+
outputs:
37+
dataprovider: ${{ steps.filter.outputs.dataprovider }}
38+
lql: ${{ steps.filter.outputs.lql }}
39+
migration: ${{ steps.filter.outputs.migration }}
40+
sync: ${{ steps.filter.outputs.sync }}
41+
gatekeeper: ${{ steps.filter.outputs.gatekeeper }}
42+
samples: ${{ steps.filter.outputs.samples }}
43+
dashboard: ${{ steps.filter.outputs.dashboard }}
44+
steps:
45+
- uses: actions/checkout@v4
46+
47+
- uses: dorny/paths-filter@v3
48+
id: filter
49+
with:
50+
filters: |
51+
dataprovider:
52+
- 'DataProvider/**'
53+
- 'Directory.Build.props'
54+
- 'Directory.Packages.props'
55+
lql:
56+
- 'Lql/**'
57+
- 'DataProvider/**'
58+
- 'Directory.Build.props'
59+
- 'Directory.Packages.props'
60+
migration:
61+
- 'Migration/**'
62+
- 'Directory.Build.props'
63+
- 'Directory.Packages.props'
64+
sync:
65+
- 'Sync/**'
66+
- 'Migration/**'
67+
- 'Directory.Build.props'
68+
- 'Directory.Packages.props'
69+
gatekeeper:
70+
- 'Gatekeeper/**'
71+
- 'DataProvider/**'
72+
- 'Migration/**'
73+
- 'Directory.Build.props'
74+
- 'Directory.Packages.props'
75+
samples:
76+
- 'Samples/**'
77+
- 'DataProvider/**'
78+
- 'Sync/**'
79+
- 'Migration/**'
80+
- 'Gatekeeper/**'
81+
- 'Directory.Build.props'
82+
- 'Directory.Packages.props'
83+
dashboard:
84+
- 'Samples/Dashboard/**'
85+
- 'Samples/Clinical/**'
86+
- 'Samples/Scheduling/**'
87+
- 'DataProvider/**'
88+
- 'Sync/**'
89+
- 'Migration/**'
90+
- 'Gatekeeper/**'
91+
- 'Directory.Build.props'
92+
- 'Directory.Packages.props'
93+
1694
build:
1795
name: Build
1896
runs-on: ubuntu-latest
@@ -46,22 +124,59 @@ jobs:
46124
- name: Build
47125
run: dotnet build --no-restore -c Release
48126

49-
# Tests that only need SQLite (no Docker)
50-
unit-tests:
51-
name: Unit Tests
127+
# DataProvider tests
128+
dataprovider-tests:
129+
name: DataProvider Tests
52130
runs-on: ubuntu-latest
53-
needs: build
131+
needs: [build, changes]
132+
if: needs.changes.outputs.dataprovider == 'true'
54133
strategy:
55134
fail-fast: false
56135
matrix:
57136
project:
58137
- DataProvider/DataProvider.Tests
59138
- DataProvider/DataProvider.Example.Tests
139+
steps:
140+
- uses: actions/checkout@v4
141+
142+
- name: Setup .NET
143+
uses: actions/setup-dotnet@v4
144+
with:
145+
dotnet-version: ${{ env.DOTNET_VERSION }}
146+
147+
- name: Cache NuGet packages
148+
uses: actions/cache@v4
149+
with:
150+
path: ~/.nuget/packages
151+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
152+
restore-keys: |
153+
${{ runner.os }}-nuget-
154+
155+
- name: Restore
156+
run: dotnet restore ${{ matrix.project }}
157+
158+
- name: Test
159+
run: dotnet test ${{ matrix.project }} --no-restore --verbosity normal --logger "trx;LogFileName=test-results.trx"
160+
161+
- name: Upload test results
162+
uses: actions/upload-artifact@v4
163+
if: always()
164+
with:
165+
name: test-results-dataprovider-${{ strategy.job-index }}
166+
path: '**/TestResults/*.trx'
167+
168+
# LQL tests
169+
lql-tests:
170+
name: LQL Tests
171+
runs-on: ubuntu-latest
172+
needs: [build, changes]
173+
if: needs.changes.outputs.lql == 'true'
174+
strategy:
175+
fail-fast: false
176+
matrix:
177+
project:
60178
- Lql/Lql.Tests
61179
- Lql/LqlCli.SQLite.Tests
62-
- Migration/Migration.Tests
63-
- Sync/Sync.Tests
64-
- Sync/Sync.SQLite.Tests
65180
steps:
66181
- uses: actions/checkout@v4
67182

@@ -88,34 +203,63 @@ jobs:
88203
uses: actions/upload-artifact@v4
89204
if: always()
90205
with:
91-
name: test-results-unit-${{ strategy.job-index }}
206+
name: test-results-lql-${{ strategy.job-index }}
92207
path: '**/TestResults/*.trx'
93208

94-
# API integration tests (SQLite, no Docker)
95-
api-tests:
96-
name: API Tests
209+
# Migration tests
210+
migration-tests:
211+
name: Migration Tests
97212
runs-on: ubuntu-latest
98-
needs: build
213+
needs: [build, changes]
214+
if: needs.changes.outputs.migration == 'true'
215+
steps:
216+
- uses: actions/checkout@v4
217+
218+
- name: Setup .NET
219+
uses: actions/setup-dotnet@v4
220+
with:
221+
dotnet-version: ${{ env.DOTNET_VERSION }}
222+
223+
- name: Cache NuGet packages
224+
uses: actions/cache@v4
225+
with:
226+
path: ~/.nuget/packages
227+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
228+
restore-keys: |
229+
${{ runner.os }}-nuget-
230+
231+
- name: Restore
232+
run: dotnet restore Migration/Migration.Tests
233+
234+
- name: Test
235+
run: dotnet test Migration/Migration.Tests --no-restore --verbosity normal --logger "trx;LogFileName=test-results.trx"
236+
237+
- name: Upload test results
238+
uses: actions/upload-artifact@v4
239+
if: always()
240+
with:
241+
name: test-results-migration
242+
path: '**/TestResults/*.trx'
243+
244+
# Sync SQLite tests (no Docker)
245+
sync-sqlite-tests:
246+
name: Sync SQLite Tests
247+
runs-on: ubuntu-latest
248+
needs: [build, changes]
249+
if: needs.changes.outputs.sync == 'true'
99250
strategy:
100251
fail-fast: false
101252
matrix:
102253
project:
103-
- Gatekeeper/Gatekeeper.Api.Tests
104-
- Samples/Clinical/Clinical.Api.Tests
105-
- Samples/Scheduling/Scheduling.Api.Tests
106-
- Samples/Dashboard/Dashboard.Web.Tests
254+
- Sync/Sync.Tests
255+
- Sync/Sync.SQLite.Tests
107256
steps:
108257
- uses: actions/checkout@v4
109258

110259
- name: Setup .NET
111260
uses: actions/setup-dotnet@v4
112261
with:
113-
dotnet-version: |
114-
8.0.x
115-
${{ env.DOTNET_VERSION }}
116-
117-
- name: Restore .NET tools
118-
run: dotnet tool restore
262+
dotnet-version: ${{ env.DOTNET_VERSION }}
119263

120264
- name: Cache NuGet packages
121265
uses: actions/cache@v4
@@ -135,14 +279,15 @@ jobs:
135279
uses: actions/upload-artifact@v4
136280
if: always()
137281
with:
138-
name: test-results-api-${{ strategy.job-index }}
282+
name: test-results-sync-sqlite-${{ strategy.job-index }}
139283
path: '**/TestResults/*.trx'
140284

141-
# Tests that need Docker for Postgres (via Testcontainers)
142-
postgres-tests:
143-
name: Postgres Tests
285+
# Sync Postgres tests (need Docker)
286+
sync-postgres-tests:
287+
name: Sync Postgres Tests
144288
runs-on: ubuntu-latest
145-
needs: build
289+
needs: [build, changes]
290+
if: needs.changes.outputs.sync == 'true'
146291
strategy:
147292
fail-fast: false
148293
matrix:
@@ -172,21 +317,103 @@ jobs:
172317
- name: Test
173318
run: dotnet test ${{ matrix.project }} --no-restore --verbosity normal --logger "trx;LogFileName=test-results.trx"
174319
env:
175-
# Testcontainers will automatically use the Docker daemon
176320
TESTCONTAINERS_RYUK_DISABLED: false
177321

178322
- name: Upload test results
179323
uses: actions/upload-artifact@v4
180324
if: always()
181325
with:
182-
name: test-results-postgres-${{ strategy.job-index }}
326+
name: test-results-sync-postgres-${{ strategy.job-index }}
327+
path: '**/TestResults/*.trx'
328+
329+
# Gatekeeper API tests
330+
gatekeeper-tests:
331+
name: Gatekeeper Tests
332+
runs-on: ubuntu-latest
333+
needs: [build, changes]
334+
if: needs.changes.outputs.gatekeeper == 'true'
335+
steps:
336+
- uses: actions/checkout@v4
337+
338+
- name: Setup .NET
339+
uses: actions/setup-dotnet@v4
340+
with:
341+
dotnet-version: ${{ env.DOTNET_VERSION }}
342+
343+
- name: Cache NuGet packages
344+
uses: actions/cache@v4
345+
with:
346+
path: ~/.nuget/packages
347+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
348+
restore-keys: |
349+
${{ runner.os }}-nuget-
350+
351+
- name: Restore
352+
run: dotnet restore Gatekeeper/Gatekeeper.Api.Tests
353+
354+
- name: Test
355+
run: dotnet test Gatekeeper/Gatekeeper.Api.Tests --no-restore --verbosity normal --logger "trx;LogFileName=test-results.trx"
356+
357+
- name: Upload test results
358+
uses: actions/upload-artifact@v4
359+
if: always()
360+
with:
361+
name: test-results-gatekeeper
362+
path: '**/TestResults/*.trx'
363+
364+
# Sample API tests
365+
sample-api-tests:
366+
name: Sample API Tests
367+
runs-on: ubuntu-latest
368+
needs: [build, changes]
369+
if: needs.changes.outputs.samples == 'true'
370+
strategy:
371+
fail-fast: false
372+
matrix:
373+
project:
374+
- Samples/Clinical/Clinical.Api.Tests
375+
- Samples/Scheduling/Scheduling.Api.Tests
376+
- Samples/Dashboard/Dashboard.Web.Tests
377+
steps:
378+
- uses: actions/checkout@v4
379+
380+
- name: Setup .NET
381+
uses: actions/setup-dotnet@v4
382+
with:
383+
dotnet-version: |
384+
8.0.x
385+
${{ env.DOTNET_VERSION }}
386+
387+
- name: Restore .NET tools
388+
run: dotnet tool restore
389+
390+
- name: Cache NuGet packages
391+
uses: actions/cache@v4
392+
with:
393+
path: ~/.nuget/packages
394+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
395+
restore-keys: |
396+
${{ runner.os }}-nuget-
397+
398+
- name: Restore
399+
run: dotnet restore ${{ matrix.project }}
400+
401+
- name: Test
402+
run: dotnet test ${{ matrix.project }} --no-restore --verbosity normal --logger "trx;LogFileName=test-results.trx"
403+
404+
- name: Upload test results
405+
uses: actions/upload-artifact@v4
406+
if: always()
407+
with:
408+
name: test-results-sample-api-${{ strategy.job-index }}
183409
path: '**/TestResults/*.trx'
184410

185411
# Dashboard E2E tests (need Playwright browser)
186412
e2e-tests:
187413
name: Dashboard E2E Tests
188414
runs-on: ubuntu-latest
189-
needs: build
415+
needs: [build, changes]
416+
if: needs.changes.outputs.dashboard == 'true'
190417
steps:
191418
- uses: actions/checkout@v4
192419

0 commit comments

Comments
 (0)