mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
1b27babd17
zizmor (static analysis for GitHub Actions) now runs twice: locally before a
workflow commit (hard rule in .claude/CLAUDE.md) and as the `zizmor` job next to
the pin gate in action-pins.yml (zizmorcore/zizmor-action pinned by SHA, zizmor
1.30.1 pinned, SARIF into Code scanning, severity low and above). Like the pin
gate it reports and does not block. zizmor.yml holds the single reasoned ignore.
Baseline fixes so the gate starts green:
- persist-credentials: false on every checkout except combine-rules.yml, the one
job that pushes with the checkout credentials (ignored in zizmor.yml, with reason)
- publish-scripts.yml: id-token: write moves from the workflow to the publish job;
indexnow-notify.yml: permissions: {}
- deploy-mcp.yml: env values referenced as shell variables inside bash steps
instead of template expansion
- pester.yml / publish-scripts.yml: reusable workflow via the self-repository form
$/ (GitHub changelog 2026-07-30); the pin gate treats $/ like ./
- combine-rules.yml: ajv-cli installed with npm ci from rules/scripts/package-lock.json
(no ts-node peer, no lifecycle scripts) instead of an ad-hoc global install;
Dependabot watches /rules/scripts
- azure/login pin comment corrected to the tag the SHA actually is (v3.0.2; v3
moved on to v3.1.0), no runtime change
- Dependabot: 7-day cooldown on every ecosystem (security updates are exempt)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
252 lines
9.4 KiB
YAML
252 lines
9.4 KiB
YAML
name: CI
|
|
|
|
# Tests, typechecks and drift-checks every push to main and every pull request:
|
|
# the .NET suites, the web and MCP suites, and a guard that the generated rule
|
|
# files still match rules/guardrails.json.
|
|
#
|
|
# The deploy workflows build but never test, so this is the only place the suites
|
|
# actually run. It does not gate anything — main is deliberately unprotected, so a
|
|
# red run reports rather than blocks. Read the result and follow up.
|
|
#
|
|
# Path filters: commits that only bump a private submodule gitlink (internal/, infra/,
|
|
# .claude/commands), touch prose or edit another workflow cannot change anything the
|
|
# suites cover, so they are skipped instead of burning ~15 runner-minutes each. A gitlink bump reports the bare
|
|
# path ('internal', no trailing slash), which 'internal/**' does NOT match — both forms
|
|
# are listed. GitHub skips only when EVERY changed path matches; a commit that touches
|
|
# docs AND code still runs.
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths-ignore:
|
|
- 'internal'
|
|
- 'internal/**'
|
|
- 'infra'
|
|
- 'infra/**'
|
|
- '.claude/**'
|
|
- '.gitmodules'
|
|
- 'zizmor.yml'
|
|
- '**/*.md'
|
|
- 'LICENSE'
|
|
- '.github/ISSUE_TEMPLATE/**'
|
|
- '.github/FUNDING.yml'
|
|
- '.github/dependabot.yml'
|
|
- '.github/assets/**'
|
|
- '.github/codeql/**'
|
|
- '.github/scripts/**'
|
|
# Every other workflow: nothing here builds or tests anything CI covers. paths-ignore
|
|
# cannot negate, so they are listed one by one; ci.yml itself stays out of the list
|
|
# so a change to CI runs CI. A new workflow file is opt-in — add it here too.
|
|
- '.github/workflows/action-pins.yml'
|
|
- '.github/workflows/bootstrap-script-gates.yml'
|
|
- '.github/workflows/build-agent.yml'
|
|
- '.github/workflows/build-msi.yml'
|
|
- '.github/workflows/codeql.yml'
|
|
- '.github/workflows/combine-rules.yml'
|
|
- '.github/workflows/deploy-backend.yml'
|
|
- '.github/workflows/deploy-mcp.yml'
|
|
- '.github/workflows/deploy-web.yml'
|
|
- '.github/workflows/indexnow-notify.yml'
|
|
- '.github/workflows/oidc-login-test.yml'
|
|
- '.github/workflows/pester.yml'
|
|
- '.github/workflows/publish-scripts.yml'
|
|
pull_request:
|
|
branches: [main]
|
|
paths-ignore:
|
|
- 'internal'
|
|
- 'internal/**'
|
|
- 'infra'
|
|
- 'infra/**'
|
|
- '.claude/**'
|
|
- '.gitmodules'
|
|
- 'zizmor.yml'
|
|
- '**/*.md'
|
|
- 'LICENSE'
|
|
- '.github/ISSUE_TEMPLATE/**'
|
|
- '.github/FUNDING.yml'
|
|
- '.github/dependabot.yml'
|
|
- '.github/assets/**'
|
|
- '.github/codeql/**'
|
|
- '.github/scripts/**'
|
|
# Every other workflow: nothing here builds or tests anything CI covers. paths-ignore
|
|
# cannot negate, so they are listed one by one; ci.yml itself stays out of the list
|
|
# so a change to CI runs CI. A new workflow file is opt-in — add it here too.
|
|
- '.github/workflows/action-pins.yml'
|
|
- '.github/workflows/bootstrap-script-gates.yml'
|
|
- '.github/workflows/build-agent.yml'
|
|
- '.github/workflows/build-msi.yml'
|
|
- '.github/workflows/codeql.yml'
|
|
- '.github/workflows/combine-rules.yml'
|
|
- '.github/workflows/deploy-backend.yml'
|
|
- '.github/workflows/deploy-mcp.yml'
|
|
- '.github/workflows/deploy-web.yml'
|
|
- '.github/workflows/indexnow-notify.yml'
|
|
- '.github/workflows/oidc-login-test.yml'
|
|
- '.github/workflows/pester.yml'
|
|
- '.github/workflows/publish-scripts.yml'
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
dotnet:
|
|
name: .NET tests (backend + agent)
|
|
# windows-latest is required: the agent test projects target net48.
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
|
|
with:
|
|
dotnet-version: '10.0.x'
|
|
|
|
- name: Restore
|
|
run: dotnet restore AutopilotMonitor.sln
|
|
|
|
- name: Build
|
|
run: dotnet build AutopilotMonitor.sln --configuration Release --no-restore
|
|
|
|
- name: Backend tests
|
|
run: dotnet test src/Backend/AutopilotMonitor.Functions.Tests --configuration Release --no-build --verbosity quiet --logger "console;verbosity=minimal"
|
|
|
|
- name: Agent V2 Core tests
|
|
run: dotnet test src/Agent/AutopilotMonitor.Agent.V2.Core.Tests --configuration Release --no-build --verbosity quiet --logger "console;verbosity=minimal"
|
|
|
|
- name: Decision Core tests
|
|
run: dotnet test src/Agent/AutopilotMonitor.DecisionCore.Tests --configuration Release --no-build --verbosity quiet --logger "console;verbosity=minimal"
|
|
|
|
- name: Summary Dialog tests
|
|
run: dotnet test src/Agent/AutopilotMonitor.SummaryDialog.Tests --configuration Release --no-build --verbosity quiet --logger "console;verbosity=minimal"
|
|
|
|
web:
|
|
name: Web (typecheck + tests)
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: src/Web/autopilot-monitor-web
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: '22'
|
|
cache: npm
|
|
cache-dependency-path: src/Web/autopilot-monitor-web/package-lock.json
|
|
|
|
- run: npm ci
|
|
|
|
# next-env.d.ts + .next type stubs are gitignored (Next-managed since
|
|
# v16); typegen generates them so tsc sees the same types as a build.
|
|
- name: Generate Next.js types
|
|
run: npx next typegen
|
|
|
|
- name: Typecheck
|
|
run: npx tsc --noEmit
|
|
|
|
# Errors fail outright, and so does ANY warning: the codebase is
|
|
# warning-clean and must stay that way — fix new findings, never
|
|
# raise the cap.
|
|
- name: Lint
|
|
run: npm run lint -- --max-warnings 0
|
|
|
|
- name: Tests
|
|
run: npm test
|
|
|
|
mcp:
|
|
name: MCP server tests
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: src/McpServer/autopilot-monitor-mcp
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: '22'
|
|
cache: npm
|
|
cache-dependency-path: src/McpServer/autopilot-monitor-mcp/package-lock.json
|
|
|
|
- run: npm ci
|
|
|
|
- name: Typecheck
|
|
run: npx tsc --noEmit
|
|
|
|
# The vector-search tests tokenize with the real all-MiniLM-L6-v2 model
|
|
# (~23 MB tokenizer + ONNX weights). transformers.js caches under
|
|
# node_modules by default, which npm ci recreates — so every CI run
|
|
# re-downloaded from huggingface.co and rate-limits (429) failed the job
|
|
# (run 31252869254). Persist the model across runs instead; HF_CACHE_DIR
|
|
# is honored by vector-search-provider.ts.
|
|
- name: Cache embedding model
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
with:
|
|
path: ${{ github.workspace }}/.hf-cache
|
|
key: hf-model-Xenova-all-MiniLM-L6-v2
|
|
|
|
- name: Tests
|
|
run: npm test
|
|
env:
|
|
HF_CACHE_DIR: ${{ github.workspace }}/.hf-cache
|
|
|
|
guardrails-in-sync:
|
|
name: Generated guardrails match rules/guardrails.json
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: '22'
|
|
|
|
- name: Regenerate
|
|
run: node rules/scripts/combine.js
|
|
|
|
- name: Fail if the generated files drifted
|
|
run: |
|
|
if ! git diff --quiet; then
|
|
echo "::error::Generated files are out of date. Run 'node rules/scripts/combine.js' and commit the result."
|
|
git diff --stat
|
|
exit 1
|
|
fi
|
|
|
|
shared-manifests-in-sync:
|
|
name: Generated wire types match shared-manifests.json
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: '22'
|
|
|
|
# JSON ↔ C# parity is the dotnet job's SharedManifestParityTests; this job pins
|
|
# JSON ↔ generated TS (shared-manifests.generated.ts, wire-types.generated.ts and the
|
|
# MCP's wire-types + wire-vocabularies copies - the vocabularies are what the MCP
|
|
# tool input schemas derive their z.enum() from).
|
|
- name: Regenerate
|
|
run: node scripts/generate-shared-manifest-types.js
|
|
working-directory: src/Web/autopilot-monitor-web
|
|
|
|
- name: Fail if the generated files drifted
|
|
run: |
|
|
if ! git diff --quiet -- src/Web/autopilot-monitor-web/utils/shared-manifests.generated.ts src/Web/autopilot-monitor-web/utils/wire-types.generated.ts src/McpServer/autopilot-monitor-mcp/src/generated/wire-types.generated.ts src/McpServer/autopilot-monitor-mcp/src/generated/wire-vocabularies.generated.ts; then
|
|
echo "::error::Generated wire types are out of date. Run 'npm run generate:manifests' in src/Web/autopilot-monitor-web and commit the result."
|
|
git diff --stat
|
|
exit 1
|
|
fi
|