-
Notifications
You must be signed in to change notification settings - Fork 4
158 lines (138 loc) · 5.15 KB
/
Copy pathapps-api-openapi-drift.yml
File metadata and controls
158 lines (138 loc) · 5.15 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
name: openapi-drift
# Catch apps/ui schema drift in the apps/api PR that introduced it.
# Before this job, drift only surfaced in infra/compose's
# full-stack-smoke workflow — which runs only on infra pushes, so drift
# would sit on apps/api main until someone touched infra.
on:
push:
branches: [main]
pull_request:
concurrency:
group: apps-api-openapi-drift-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
drift:
name: apps/ui OpenAPI schema is fresh
runs-on: ubuntu-24.04
timeout-minutes: 8
# The job always runs (so the required-status-check rule on `main` is
# always satisfied), but the heavy boot-the-api / regen-schema steps
# only fire when something API- or schema-related actually changed.
# Mirrors the pattern in infra-compose-validate-compose.yml.
services:
postgres:
image: postgres:17-alpine@sha256:979c4379dd698aba0b890599a6104e082035f98ef31d9b9291ec22f2b13059ca
env:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: app_dev_password
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U app -d app"
--health-interval 5s
--health-timeout 5s
--health-retries 10
valkey:
image: valkey/valkey:8-alpine@sha256:77643d152547b446fc15cbafaff22004545663fcd40c6b28038ad283837baa75
ports:
- 6379:6379
options: >-
--health-cmd "valkey-cli ping"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
NODE_ENV: development
DATABASE_URL: postgresql://app:app_dev_password@localhost:5432/app
JWT_SECRET: ci-only-jwt-secret-padded-to-thirty-two-chars
FRONTEND_URL: http://localhost:7331
ALLOWED_ORIGINS: http://localhost:7331
APP_NAME: API Template
LOG_LEVEL: warn
EMAIL_PROVIDER: resend
RESEND_API_KEY: ""
EMAIL_FROM: noreply@example.com
VALKEY_HOST: localhost
VALKEY_PORT: "6379"
steps:
- name: Checkout monorepo
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Detect relevant changes
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: filter
with:
filters: |
code:
- 'apps/api/src/**'
- 'apps/api/package.json'
- 'apps/api/bun.lock'
- 'apps/ui/src/lib/api/schema.d.ts'
- '.github/workflows/apps-api-openapi-drift.yml'
- name: No-op (nothing relevant changed)
if: steps.filter.outputs.code != 'true'
run: echo "No API or generated-schema files changed — drift check is a no-op."
- name: Set up Bun
if: steps.filter.outputs.code == 'true'
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14
- name: Cache bun install
if: steps.filter.outputs.code == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('apps/api/bun.lock', 'apps/ui/bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-
- name: Install apps/api deps
if: steps.filter.outputs.code == 'true'
working-directory: apps/api
run: bun install --frozen-lockfile
- name: Apply DB migrations
if: steps.filter.outputs.code == 'true'
working-directory: apps/api
run: bun run db:migrate
- name: Build email templates
if: steps.filter.outputs.code == 'true'
working-directory: apps/api
run: bun run build:templates
- name: Boot API
if: steps.filter.outputs.code == 'true'
working-directory: apps/api
run: |
bun run src/index.ts &
echo "API_PID=$!" >> "$GITHUB_ENV"
for i in {1..30}; do
if curl -fsS http://localhost:7330/swagger/json > /dev/null 2>&1; then
echo "✓ api ready after ${i}s"
exit 0
fi
sleep 1
done
echo "✗ api did not become reachable in 30s" >&2
exit 1
- name: Install apps/ui deps
if: steps.filter.outputs.code == 'true'
working-directory: apps/ui
run: bun install --frozen-lockfile
- name: Check apps/ui schema is up-to-date
if: steps.filter.outputs.code == 'true'
working-directory: apps/ui
env:
OPENAPI_URL: http://localhost:7330/swagger/json
run: |
if ! bun run generate:api:check; then
echo "::error::apps/ui/src/lib/api/schema.d.ts is stale against this API change."
echo "::error::To fix: boot api on :7330, then from repo root run 'bun run regen' and commit apps/ui in the same PR."
exit 1
fi
- name: Stop API
if: always() && steps.filter.outputs.code == 'true'
working-directory: ${{ github.workspace }}
run: |
if [ -n "${API_PID:-}" ]; then
kill "$API_PID" 2>/dev/null || true
fi