-
Notifications
You must be signed in to change notification settings - Fork 0
120 lines (111 loc) · 4.21 KB
/
Copy pathci.yml
File metadata and controls
120 lines (111 loc) · 4.21 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
name: CI
# Aide moves real money and is driven by a model, for users who cannot see the
# screen to notice something went wrong. Every push runs the same gates a
# reviewer would run by hand, in parallel, so a red check is visible before a
# merge rather than after a withdrawal.
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
# A second push to the same branch makes the first run irrelevant.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
# lib/env.ts refuses to load without these, so `next build` cannot even import
# the payment routes unless they are present. CI never reaches a real
# provider — placeholders are the point: they prove the wiring, not the keys.
MONNIFY_API_KEY: ci-placeholder
MONNIFY_SECRET_KEY: ci-placeholder
MONNIFY_CONTRACT_CODE: "0000000000"
DEEPSEEK_API_KEY: ci-placeholder
NEXT_PUBLIC_CONVEX_URL: https://ci-placeholder.convex.cloud
# Every job carries its own cap. GitHub's default is 360 minutes, which is not
# a timeout so much as an absence of one: a hung job leaves the required check
# reporting neither pass nor fail for six hours and bills the whole time. There
# is a live way to hang here — app/api/tts/route.ts spawns a Python worker at
# module load whenever NEXT_RUNTIME is not "edge" and VERCEL is unset, both true
# under vitest, so an open handle can keep the runner alive past every test
# having passed. Sized to a few times what each job actually takes.
jobs:
typecheck:
name: Types
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run typecheck
test:
name: Tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
# Two vitest projects run here: plain Node for the money, agent and speech
# suites, and an edge-runtime VM for the Convex functions, which is the
# only environment convex-test can drive.
- run: npm test
build:
name: Production build
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
speech:
name: Speech worker
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
# The neural voice is not a nice-to-have here — it is the entire
# interface. Both speech entry points guard their entry behind
# __main__, so importing them is safe and proves more than a syntax
# check: that edge-tts still installs and that the names these files
# reach for still exist. A break here would otherwise reach the user as
# the robotic browser fallback voice, with nothing on screen to explain it.
- run: pip install -r requirements.txt
- name: Import both speech entry points
run: |
python -c "import sys; sys.path[:0] = ['scripts', 'api']; import tts_worker, speak"
secrets:
name: No secrets committed
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Refuse tracked env files and local Convex state
run: |
bad=$(git ls-files | grep -E '^(\.env($|\..*)|\.convex/)' | grep -v '^\.env\.example$' || true)
if [ -n "$bad" ]; then
echo "::error::These must never be committed:"; echo "$bad"; exit 1
fi
- name: Refuse live-looking credentials
run: |
# .env.example carries placeholders only (MK_TEST_xxx, sk-xxxxxxxx),
# so these patterns match real keys and nothing else.
if git grep -nIE 'MK_PROD_[A-Za-z0-9]{6,}|sk-[A-Za-z0-9]{24,}|-----BEGIN [A-Z ]*PRIVATE KEY-----' -- . ':!.github/workflows/ci.yml'; then
echo "::error::A live-looking credential is committed."; exit 1
fi