-
Notifications
You must be signed in to change notification settings - Fork 1
230 lines (219 loc) · 9 KB
/
Copy pathci.yml
File metadata and controls
230 lines (219 loc) · 9 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
name: CI
on:
pull_request:
branches: [develop, develop-auto, main]
types: [opened, synchronize, reopened]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run lint
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run typecheck
# Assistant KB freshness (#970, MAJOR-1). The grounding digest
# (digest.generated.md) is a committed build artifact distilled from the
# repo docs by scripts/build-assistant-kb.ts. If a source doc or the
# source manifest changes but the digest isn't regenerated, the assistant
# ships stale grounding. Rebuild it here and fail if the committed copy
# differs — the build is deterministic, so a clean tree means in-sync.
assistant-kb-freshness:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- name: Rebuild assistant KB digest
working-directory: ornn-api
run: bun run build:assistant-kb
- name: Fail if the committed digest is stale
run: |
git diff --exit-code -- ornn-api/src/domains/assistant/kb/digest.generated.md \
|| { echo "::error::assistant KB digest is stale — run 'bun run build:assistant-kb' in ornn-api/ and commit the result"; exit 1; }
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run test:coverage
# ornn-api line-coverage floor (#889). Bun's bunfig `coverageThreshold`
# is silently ignored on the pinned Bun (1.3.x) — it prints the table
# but never fails the run — so the floor is enforced here by summing
# LH/LF across the lcov that `test:coverage` just wrote. ornn-web's
# floor is enforced inside the run by vitest `thresholds.lines` in
# ornn-web/vitest.config.ts. Floor = operator's ≥75% gate; ratchet up
# in a reviewed one-line diff as real coverage rises (measured 96.6%).
- name: Enforce ornn-api line-coverage floor (>=75%)
run: |
awk -F: '
/^LF:/ { lf += $2 }
/^LH:/ { lh += $2 }
END {
if (lf == 0) { print "no lines found in lcov"; exit 1 }
pct = 100 * lh / lf
printf "ornn-api line coverage: %.2f%% (%d/%d), floor 75%%\n", pct, lh, lf
if (pct < 75) { print "::error::ornn-api line coverage below 75% floor"; exit 1 }
}
' ornn-api/coverage/lcov.info
# Codecov upload (#471, #889). No token needed for public repos.
# The pooled `bun` flag was split per-package so each workspace's
# lcov is attributed to its own flag (`api` / `web` / `sdk-ts`) and
# judged on its own target in codecov.yml. One upload step per flag
# because a single codecov-action invocation applies one flag set to
# every file it uploads.
- name: Upload ornn-api coverage to Codecov
uses: codecov/codecov-action@v7
if: ${{ !cancelled() }}
with:
flags: api
fail_ci_if_error: false
files: ./ornn-api/coverage/lcov.info
- name: Upload ornn-web coverage to Codecov
uses: codecov/codecov-action@v7
if: ${{ !cancelled() }}
with:
flags: web
fail_ci_if_error: false
files: ./ornn-web/coverage/lcov.info
- name: Upload TS SDK coverage to Codecov
uses: codecov/codecov-action@v7
if: ${{ !cancelled() }}
with:
flags: sdk-ts
fail_ci_if_error: false
files: ./sdk/typescript/coverage/lcov.info
python-sdk-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
cache: pip
cache-dependency-path: sdk/python/pyproject.toml
- name: Install ornn-sdk (python)
working-directory: sdk/python
run: pip install -e ".[dev]"
- name: Lint (ruff)
working-directory: sdk/python
run: ruff check .
- name: Format check (ruff)
working-directory: sdk/python
run: ruff format --check .
- name: Type check (mypy)
working-directory: sdk/python
run: mypy
- name: Run pytest with coverage
working-directory: sdk/python
run: pytest -q --cov=src/ornn_sdk --cov-report=xml --cov-report=term
# Codecov upload (#471) — same as the bun job but for the
# Python SDK's coverage.xml.
- name: Upload Python coverage to Codecov
uses: codecov/codecov-action@v7
if: ${{ !cancelled() }}
with:
flags: python
fail_ci_if_error: false
files: ./sdk/python/coverage.xml
# Audit the Python SDK's transitive deps for known CVEs (#445).
# We install the runtime deps directly (httpx + dev tools) rather
# than `pip install -e .` because pip-audit refuses editable
# installs of packages that aren't on PyPI yet (ornn-sdk is held
# for v1 per #473). The audit walks the resolved env via the OSV
# database — transitive deps (h11, anyio, certifi, idna, …) are
# all covered.
python-sdk-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install runtime + dev deps directly
working-directory: sdk/python
# Read the bounds from pyproject.toml without installing
# ornn-sdk itself. tomllib is stdlib in 3.11+; we're on 3.12.
run: |
python -c "
import tomllib, subprocess, sys
cfg = tomllib.load(open('pyproject.toml', 'rb'))
deps = cfg['project']['dependencies']
deps += cfg['project']['optional-dependencies']['dev']
subprocess.check_call([sys.executable, '-m', 'pip', 'install', *deps])
"
# pip itself is in the audited env — keep it current (PYSEC-2026-196, #935)
python -m pip install --upgrade pip
pip install pip-audit
- name: Audit dependencies
working-directory: sdk/python
# `--strict` fails on any known CVE in the installed env.
run: pip-audit --strict
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build:web
gitleaks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install gitleaks
run: |
VERSION=$(curl -sI https://github.com/gitleaks/gitleaks/releases/latest | grep -i location | grep -oE 'v[0-9.]+' | head -1 | sed 's/^v//')
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" | tar xz
sudo mv gitleaks /usr/local/bin/
- name: Scan for secrets
run: gitleaks detect --source . --log-opts="origin/${{ github.base_ref }}..HEAD" --verbose
audit:
# Fails on any high or critical advisory in the Bun workspace. Moderate
# and below print to the PR step summary but don't block — Dependabot
# picks them up on the weekly cadence (.github/dependabot.yml).
#
# Ignored advisories — accepted residual risk documented in #385:
# GHSA-r5fr-rjxr-66jc lodash-es high (via mermaid)
# GHSA-f23m-r3pf-42rh lodash-es moderate (via mermaid)
# lodash-es is archived at 4.17.21 with no upstream fix; the vulnerable
# APIs (_.template / _.unset / _.omit) are not reachable through
# mermaid's surface under our usage.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- name: Audit (high+critical block PR)
run: bun audit --audit-level=high --ignore=GHSA-r5fr-rjxr-66jc --ignore=GHSA-f23m-r3pf-42rh
- name: Audit summary (moderate+ — informational)
if: ${{ !cancelled() }}
run: |
{
echo "### bun audit — full report (moderate and above)"
echo ""
echo '```'
bun audit --audit-level=moderate || true
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- name: Build ornn-api image
run: docker build -t ornn-api-ci -f ornn-api/Dockerfile .
- name: Build ornn-web image
# Runtime-config (PR #117) dropped all VITE_* build args — the image
# is environment-agnostic, config.js is rendered from its template at
# container startup via envsubst. CI just verifies the Dockerfile
# builds cleanly.
run: docker build -t ornn-web-ci -f ornn-web/Dockerfile .