-
Notifications
You must be signed in to change notification settings - Fork 6
381 lines (354 loc) · 16.5 KB
/
Copy pathci.yml
File metadata and controls
381 lines (354 loc) · 16.5 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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# Continuous-integration gates — run on every PR + every push to
# main. Catches frontend type errors, Go vet/test regressions, and
# the "I forgot to run `make web-build` before committing" class of
# bug that silently shipped pre-v1.6.0.
#
# Tagged-release builds are handled by npm-release.yml; this file is
# the pre-merge / pre-tag safety net.
name: ci
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
# ----------------------------------------------------------------
# React frontend gates: install, typecheck, build. Also asserts the
# committed embedded dist matches what a fresh build produces — if
# `web/src/` was edited without rerunning `make web-build`, this
# job fails with a clear actionable message. Without this gate the
# embedded bundle silently drifted from the React source.
# ----------------------------------------------------------------
frontend:
name: frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: web/package-lock.json
- name: npm ci
run: |
cd web
npm ci
- name: typecheck
run: |
cd web
npm run typecheck
- name: build
run: |
cd web
npm run build
- name: dist consistency check
# Mirrors `make web-build`'s second half: regenerates the
# embedded dir from web/dist and asserts it matches what's
# committed. If it doesn't, the dev edited web/src/ but
# forgot to commit the rebuilt bundle — a stale embed would
# ship on the next release.
run: |
set -euo pipefail
rm -rf internal/intelligence/dashboard/webapp/dist
mkdir -p internal/intelligence/dashboard/webapp/dist
cp -R web/dist/. internal/intelligence/dashboard/webapp/dist/
if ! git diff --quiet --exit-code internal/intelligence/dashboard/webapp/dist; then
echo "::error::Committed webapp/dist drifted from web/dist. Run \`make web-build\` and commit the result."
git diff --stat internal/intelligence/dashboard/webapp/dist | head -40
exit 1
fi
echo "embedded dist matches fresh build ✓"
# ----------------------------------------------------------------
# Go gates — vet, test, build. Pure-Go so no special toolchain
# beyond setup-go. Frontend build is independent (this job doesn't
# need a fresh dist to compile; the committed embed satisfies the
# //go:embed directive at compile time, even if it's stale for the
# purposes of the runtime UI).
# ----------------------------------------------------------------
go:
name: go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: vet
run: go vet ./...
- name: lint
# golangci-lint enforces the full .golangci.yml set — including
# gofumpt + goimports formatting, errorlint, gosec, gocritic, and
# gocyclo (threshold 30; see .golangci.yml for the documented
# pre-existing exclusions). Joined CI in Teams M5; the tree is clean.
uses: golangci/golangci-lint-action@v6
with:
version: v1.64.8
# Build golangci-lint from source with the runner's Go (1.25 via
# setup-go/go.mod). The prebuilt v1.64.8 binary is compiled with
# go1.24 and refuses to run against a go.mod that targets 1.25
# ("language version used to build golangci-lint is lower than the
# targeted Go version"). goinstall sidesteps that mismatch.
install-mode: goinstall
- name: test
# -race catches the watcher / proxy concurrency bugs that
# otherwise slip past until live use. -timeout 40m: the
# intelligence/dashboard suite exceeds go test's default 10m
# per-binary timeout under -race on CI runners (observed
# 2026-07-11; raised 25m→40m 2026-07-21 after the v1.22.0 suite
# blew 25m twice — no deadlock, the package is just large: every
# newTestServer runs the full migration chain, so the binary
# scales with test count × migrations on 2-core runners. The
# real fix is a template-DB copy in newTestServer.)
run: go test -race -timeout 40m ./...
- name: build
# `make build` skipped here — that target requires Node for
# web-build, which the frontend job already verified. This
# step exercises the Go compile path against the committed
# embedded dist.
run: |
mkdir -p bin
go build -trimpath -o bin/observer ./cmd/observer
GOOS=windows GOARCH=amd64 go build -trimpath -o bin/antigravity-bridge.exe ./cmd/antigravity-bridge
ls -l bin/
- name: windows cross-compile
# `go test ./...` and the build step above never compile any
# `//go:build windows` file, and the build step's only Windows
# target is cmd/antigravity-bridge — so a Windows-only break in
# internal/processobs (peb_windows.go, procmetrics_windows.go,
# enum_windows.go, and the ETW backend to come) ships undetected.
# Compile-only; these packages have no Linux-runnable tests.
run: GOOS=windows GOARCH=amd64 go build ./...
# ----------------------------------------------------------------
# Distribution README drift gate. The npm and PyPI READMEs share a
# large body (Per-AI-client setup through Configuration) sourced from
# docs/distribution/README-body.md. If a contributor edits one
# channel's README directly instead of the body file, this job fails
# with the diff and a "run `make sync-distribution-readmes`" hint.
# ----------------------------------------------------------------
distribution-readmes:
name: distribution README drift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Verify
run: make verify-distribution-readmes
# ----------------------------------------------------------------
# Website accuracy gate (SEO playbook §1.5). Same check the deploy
# workflow runs pre-publish, run here too so a PR that introduces
# stale version/adapter-count/MCP-census strings (or the retracted
# compression-savings claim, or broken JSON-LD) fails fast at review
# time instead of only at the next push-to-main deploy. node builtins
# only — no setup-node/install step needed.
# ----------------------------------------------------------------
website-accuracy:
name: website accuracy check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Verify
run: node website/tools/accuracy-check.mjs
# ----------------------------------------------------------------
# Marketing-page chrome drift gate. The top-level pages (/, /about,
# /enterprise, /newsletter, /privacy, /security, /terms) are RENDERED
# from website/pages-src/ through one shared shell that owns the
# <head>, nav and footer. This job re-renders into a temp dir and
# diffs against the committed HTML, so a hand-edit to a rendered page
# fails at review time. Before the shell existed the copy-pasted
# chrome had drifted into four #topnav variants and three footer
# variants; this is what stops that recurring. Same
# build-into-temp/never-mutate pattern as distribution-readmes.
# ----------------------------------------------------------------
website-build-drift:
name: marketing page drift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version-file: website/docs-tools/go.mod
cache-dependency-path: website/docs-tools/go.sum
- name: Verify
run: make verify-website-build
# ----------------------------------------------------------------
# Track-page drift gate. website/track-gen derives the per-adapter
# "Track <tool> costs" pages from internal/integration.Capabilities()
# (the one-owner adapter capability registry) and rewrites the
# matching marker blocks in nav.toml + sitemap.xml. It has
# historically been run by hand, so a registry change (new adapter,
# changed capability row) could ship without anyone re-running it —
# this job closes that gap the same way website-build-drift does for
# the marketing pages: regenerate into a scratch copy, diff, never
# mutate the working tree.
# ----------------------------------------------------------------
track-build-drift:
name: track page drift
runs-on: ubuntu-latest
steps:
# fetch-depth: 0 is LOAD-BEARING for this job alone. Each track page's
# sitemap <lastmod> is derived from `git log -1 --format=%cs -- <file>`
# (website/track-gen/main.go). actions/checkout defaults to a depth-1
# clone, where that command reports the TIP commit's date for every
# path — so every page dates to "today", the gate compares those against
# the real commit dates in the committed sitemap, and fails. It would
# fail every day, on every branch, whatever the content, while passing
# locally where the history is complete.
#
# This is a SECOND cause behind the same symptom that 6602276d fixed:
# that commit stopped the generator reading history from a scratch copy
# outside the working tree (where git returns nothing at all). Both had
# to be fixed; either one alone still leaves the gate red on CI.
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: Verify
run: make verify-track-build
# ----------------------------------------------------------------
# Plugin-manifest drift gate. plugins/plugingen derives the in-tool
# plugin manifests (Claude Code plugin + marketplace catalog, Cursor
# MCP install deeplink, Gemini CLI extension, Goose listing, Codex
# plugin + catalog, OpenCode package wiring) by RUNNING the real
# `observer init` registrars — internal/mcp's Registrar and
# internal/hook's Registry — against a throwaway sandbox HOME. It is
# invoked by hand (`make plugins-build`), so a registrar change (new
# hook event, changed MCP argument) could ship with the published
# plugin still declaring the old wiring. This job closes that gap
# exactly like track-build-drift: regenerate into a scratch copy, diff,
# never mutate the working tree. See
# docs/plans/adapter-plugins-distribution-plan-2026-07-31.md §3.
#
# node + web deps are here for the SECOND half of the gate: the
# OpenCode package's hand-written TypeScript is parsed with the esbuild
# vendored in web/node_modules (the verify-taxonomy-ts pattern), so a
# syntax error in glue the Go tests can only substring-check cannot
# reach an operator's `npm publish`. Nothing is installed for the
# plugin itself.
# ----------------------------------------------------------------
plugins-build-drift:
name: plugin manifest drift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: web/package-lock.json
- name: npm ci
run: |
cd web
npm ci
- name: Verify
run: make verify-plugins-build
# The public-repo assembly is a SECOND transpose on top of the
# generated tree (directory-per-surface -> repository-root, plus the
# release restamp), and it carries its own honesty gate. --self-check
# assembles twice into mktemp dirs, byte-diffs them and removes them,
# so a broken assembler or a README whose install-section anchors
# moved fails here rather than at publish time. It writes nothing
# into the working tree and publishes nothing.
- name: Verify plugins-repo assembly
run: bash scripts/assemble-plugins-repo.sh --self-check
# ----------------------------------------------------------------
# Action-taxonomy drift gate. web/taxgen mirrors internal/tooltax —
# the one owner of the cross-adapter tool/MCP taxonomy — into
# web/src/lib/actiontax.gen.*, which web/src/lib/actions.ts reads
# for its categories, action-type labels and MCP parse rules. It is
# invoked by hand (`make taxonomy-build`), so a new action type or
# category could ship with the dashboard still rendering the old
# vocabulary — which is exactly how the frontend grew its own
# divergent taxonomy before WP-T1. Same shape as plugins-build-drift:
# regenerate into a scratch dir, byte-diff, never mutate the working
# tree. See
# docs/plans/tool-taxonomy-standardization-plan-2026-07-31.md §1/§7.
#
# The second step is the CROSS-LANGUAGE half: the drift gate only
# proves the generated files match Go, so this compiles the real
# actions.ts (esbuild) and runs it against the generated vectors. It
# needs node + web deps — hence the setup-node/npm ci steps here,
# mirroring the frontend job — because a Go-side reference
# implementation of the TypeScript parser can only prove Go agrees
# with Go.
# ----------------------------------------------------------------
taxonomy-build-drift:
name: action taxonomy drift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: web/package-lock.json
- name: npm ci
run: |
cd web
npm ci
- name: Verify generated artifacts
run: make verify-taxonomy-build
- name: Verify the real TypeScript against the Go oracle
run: make verify-taxonomy-ts
- name: Verify the generated backfill migration
run: make verify-taxonomy-migration
- name: Verify the generated assistant-text relabel migration
run: make verify-assistant-migration
- name: Verify the generated reasoning convergence migration
run: make verify-reasoning-migration
# ----------------------------------------------------------------
# Helm chart smoke (Teams M5). Lint + template the observer-org chart,
# then `helm install` it into an ephemeral kind cluster to prove the
# rendered manifests are accepted by a real API server and the release
# deploys. Pod readiness is NOT asserted: the server fetches its SAML
# IdP metadata at startup, so a Ready pod needs real secrets + a
# reachable IdP that the operator supplies. Here we verify the chart
# installs cleanly and the core objects are created.
# ----------------------------------------------------------------
helm:
name: helm chart
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: azure/setup-helm@v4
with:
version: v3.21.0
- name: Lint + template
run: |
set -euo pipefail
helm lint charts/observer-org -f charts/observer-org/ci/test-values.yaml
helm template obs charts/observer-org -f charts/observer-org/ci/test-values.yaml > /dev/null
- name: Create kind cluster
uses: helm/kind-action@v1
- name: Install into kind
run: |
set -euo pipefail
kubectl create namespace obs
# Placeholder secret so the required secrets.existingSecret
# resolves. Not valid key material — the pod won't reach Ready
# (no live IdP), but the release installs and every manifest is
# validated by the real API server.
kubectl create secret generic observer-org-secrets -n obs \
--from-literal=bearer-signing.key=placeholder \
--from-literal=session.key=placeholder \
--from-literal=sp.crt=placeholder \
--from-literal=sp.key=placeholder \
--from-literal=scim-token=placeholder
helm install obs charts/observer-org -n obs \
-f charts/observer-org/ci/test-values.yaml
echo "=== release status ==="
helm status obs -n obs
echo "=== objects ==="
kubectl get deploy,svc,pvc,cm,sa -n obs
kubectl get deploy/obs-observer-org -n obs
kubectl get svc/obs-observer-org -n obs
kubectl get pvc -n obs | grep -q obs-observer-org-data
echo "Helm chart installs cleanly ✓"