Repository navigation
241 lines (202 loc) · 10.3 KB
/
Copy pathci.yml
File metadata and controls
241 lines (202 loc) · 10.3 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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
name: CI
on:
push:
branches: [main, develop]
pull_request:
# Cancel superseded runs for the same ref (e.g. rapid pushes to a PR branch).
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Third-party actions are pinned to a full commit SHA (with a trailing version
# comment) so a moved tag can't silently change what runs in CI.
jobs:
api:
name: api (lint, typecheck, test, build)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# No version input: pnpm/action-setup reads the exact version from the
# root package.json "packageManager" field.
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Install
run: pnpm install --frozen-lockfile
# `--filter ansari-api...` (trailing dots) selects the app AND its workspace
# dependencies. @ansari/eslint-config and @ansari/tsconfig appear in scope but
# define no lint/typecheck scripts, so turbo runs nothing FOR them — expect
# "3 packages in scope, 1 task".
#
# Their correctness is still enforced, indirectly and sufficiently: the app
# consumes both, so a broken base.js or base.json fails THIS step. They are also
# in turbo.json globalDependencies, so editing either busts the app's cache
# rather than replaying a stale pass. The dependency-closure filter is what makes
# that work — a bare `--filter ansari-api` would not pick up the change.
- name: Lint
run: pnpm exec turbo run lint --filter ansari-api...
# Build BEFORE the dummy env is loaded: the api build must need no env
# (#260 — nothing may read lib/config.ts at import). GITHUB_ENV only reaches
# later steps, so this run sees no DATABASE_URL/AUTH_URL, and a module-scope
# config read fails it with `Environment validation failed`.
- name: Build
run: pnpm exec turbo run build --filter ansari-api...
# The committed dummy env (apps/api/.env.ci) is the single no-secrets env
# source — every value is deliberately fake. No repository secrets are
# used anywhere in this workflow.
- name: Load CI dummy env
run: grep -v '^#' apps/api/.env.ci >> "$GITHUB_ENV"
- name: Typecheck
run: pnpm exec turbo run typecheck --filter ansari-api...
# Runs the full suite AND emits a coverage summary. Report-only — there is
# deliberately no coverage threshold gate yet.
- name: Test (with coverage)
run: pnpm exec turbo run test:coverage --filter ansari-api...
# Better Auth service (issue #59: apps/auth + packages/auth). Mirrors the `api`
# job, scoped to the auth dependency closure — `--filter ansari-auth...`
# (trailing dots) selects apps/auth AND its workspace deps, so @ansari/auth's
# lint/typecheck/test run here too. This is the ONLY job that reaches apps/auth;
# neither `ansari-api...` nor `ansari-frontend...` does. (packages/auth is ALSO
# lint+typecheck'd by the frontend job's `--filter ./packages/*` step — but that
# step runs no test/build, so its tests need this job as their home.)
auth:
name: auth (lint, typecheck, test, build)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Install
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm exec turbo run lint --filter ansari-auth...
# Committed dummy env (apps/auth/.env.ci) — every value is deliberately
# fake, no repository secrets. Loaded so any code path that reads env has
# values during typecheck/test/build.
- name: Load CI dummy env
run: grep -v '^#' apps/auth/.env.ci >> "$GITHUB_ENV"
- name: Typecheck
run: pnpm exec turbo run typecheck --filter ansari-auth...
- name: Test
run: pnpm exec turbo run test --filter ansari-auth...
- name: Build
run: pnpm exec turbo run build --filter ansari-auth...
frontend:
# Emitted name deliberately unchanged (human decision, spec 48), even though
# this job now also runs `test` and `build`. Check names are matched by
# branch protection, and this one IS a required check on `develop`
# (verified 2026-10-11, #262): renaming the job would leave the required
# check pending forever and block every PR. Any rename must be ONE
# coordinated admin change (job name + branch protection together, see
# RELEASE.md). The label lagging its contents is the accepted cost.
name: frontend (lint, typecheck)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Install
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm exec turbo run lint --filter ansari-frontend...
# `typecheck` no longer chains `gen:types` with `&&` — turbo.json declares
# `typecheck.dependsOn: ["gen:types"]`, so the graph regenerates the
# gitignored uniwind-types.d.ts before tsc runs. (build:web KEEPS its
# in-script chain: Dockerfile.web has no turbo. See turbo.json.)
- name: Typecheck
run: pnpm exec turbo run typecheck --filter ansari-frontend...
# The app's vitest suite (lib/ components/ hooks/ constants/, jsdom +
# testing-library). It never ran in CI while the app lived outside the
# workspace as the SDK 54 prototype (#262). The job name above stays
# frozen, so the required check now covers tests without a rename.
- name: Test
run: pnpm exec turbo run test --filter ansari-frontend...
# This step exists for @ansari/types specifically — the one package under
# packages/ with NO consumer, so it sits outside every app's dependency closure
# and no `--filter <app>...` can reach it. `./packages/*` now puts four packages
# in scope (eslint-config, tsconfig, types, auth); the tasks that RUN are the
# lint+typecheck of the two that define them — @ansari/types and @ansari/auth —
# so expect "4 packages in scope, 4 tasks".
#
# @ansari/auth is picked up here incidentally (lint+typecheck only); its test AND
# build coverage live in the dedicated `auth` job above via `ansari-auth...`. The
# two config packages (eslint-config, tsconfig) define no tasks and need no step:
# the apps that consume them fail if they break.
#
# Placed BEFORE the frontend build deliberately: steps are sequential and
# fail-fast, so running it after `build` would mean a build failure silently
# skips the only coverage @ansari/types gets.
- name: Lint + typecheck shared packages
run: pnpm exec turbo run lint typecheck --filter './packages/*'
# NEW in spec 48: the frontend was never built in CI. `pnpm build` now
# means "both apps", so this enforces that rather than merely claiming it.
# expo export already runs in Dockerfile.web at deploy time, so this moves
# an existing failure mode earlier rather than inventing a new one.
- name: Build
run: pnpm exec turbo run build --filter ansari-frontend...
# Python WhatsApp service (spec 321). Not part of the pnpm/turbo graph, so it
# gets its own job. conftest.py supplies mock-mode defaults, so no env or
# repository secrets are needed.
whatsapp:
name: whatsapp (lint, format, test)
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
working-directory: legacy/whatsapp
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
- name: Install
run: uv sync --frozen --extra dev
- name: Lint
run: uv run ruff check .
- name: Format check
run: uv run ruff format --check .
- name: Test
run: uv run pytest tests/ -v
gitleaks:
name: gitleaks (secret scan)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history, so the push scan covers every commit on the branch. This
# also fetches every OTHER branch; gitleaks-scan.sh scopes the scan so
# an unmerged branch's finding can't fail unrelated PRs (#175).
fetch-depth: 0
# Plain binary instead of gitleaks-action: the action requires a license
# key for organization repos; the binary is free for all use. The tarball
# is verified against its published SHA-256 checksum before extraction so
# a tampered release artifact can't run in CI.
- name: Install gitleaks
run: |
set -euo pipefail
GITLEAKS_VERSION=8.24.3
EXPECTED_SHA=9991e0b2903da4c8f6122b5c3186448b927a5da4deef1fe45271c3793f4ee29c
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" -o gitleaks.tar.gz
echo "${EXPECTED_SHA} gitleaks.tar.gz" | sha256sum -c -
tar -xzf gitleaks.tar.gz gitleaks
sudo mv gitleaks /usr/local/bin/
# PR: only the PR's own commits (origin/<base>..HEAD). Push to main/develop:
# the full history of the pushed branch.
- name: Scan
env:
BASE_REF: ${{ github.base_ref }}
run: .github/scripts/gitleaks-scan.sh
- name: Regression test scan scoping (#175)
run: .github/scripts/gitleaks-scan.test.sh