mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 03:43:11 +08:00
ci(quality-gate): route checks by import graph and add offline agent QA
This commit is contained in:
@@ -4,6 +4,8 @@ These rules apply to `.github/` changes in addition to the root instructions.
|
||||
|
||||
- Treat workflow changes as product changes. Run `bun run check:policy`; run `actionlint` when available.
|
||||
- `scripts/pr/change-policy.ts` is the source of truth for path-to-check routing. Do not duplicate the routing graph in advisory automation.
|
||||
- Routing is path prefixes plus the import graph from `scripts/pr/module-graph.ts`. Prefixes decide areas and every blocking rule; the graph only widens which surface checks run. When the graph cannot be built the run selects every surface rather than silently falling back to prefixes.
|
||||
- `nightly-quality.yml` runs every deterministic lane unconditionally and re-proves the module graph. It exists because per-PR selection can only ever cover what a diff reaches; do not move its jobs into the required PR gate.
|
||||
- Keep `pr-quality-gate` as the stable required status. Selected jobs must succeed and unselected jobs must be explicitly skipped; never convert failures into success.
|
||||
- Required PR jobs must remain offline and must not receive provider credentials or depend on paid/live services.
|
||||
- A `pull_request_target` workflow may inspect PR metadata using trusted base code, but must never execute the PR head, install PR-controlled dependencies, or expose secrets to contributor code.
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
name: Nightly Quality
|
||||
|
||||
# The PR gate is intentionally scoped: it runs only the surfaces a diff can reach.
|
||||
# That leaves two blind spots no per-PR run can close — regressions that only appear
|
||||
# when the whole suite runs together, and drift in checks no recent PR happened to
|
||||
# select. This workflow closes them on a schedule, off the contributor's critical
|
||||
# path, and still without any model, provider, or repository secret.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# 18:00 UTC = 02:00 Asia/Shanghai, after the working day.
|
||||
- cron: '0 18 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skip_coverage:
|
||||
description: 'Skip the coverage ratchet (faster smoke of the rest)'
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: nightly-quality
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
full-deterministic:
|
||||
name: full-deterministic
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version-file: package.json
|
||||
- name: Install root dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Install desktop dependencies
|
||||
working-directory: desktop
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Install adapter dependencies
|
||||
working-directory: adapters
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
# Every deterministic lane, unconditionally — no path routing, no dependency
|
||||
# graph. This is the run that catches a check the router stopped selecting.
|
||||
- name: Policy and gate regressions
|
||||
run: bun run check:policy
|
||||
- name: Deterministic agent flow
|
||||
run: bun run check:agent-flow
|
||||
- name: Root runtime tests
|
||||
run: bun run check:server
|
||||
- name: Provider contracts
|
||||
run: bun run check:provider-contract
|
||||
- name: Desktop/server chat contracts
|
||||
run: bun run check:chat-contract
|
||||
- name: Adapter tests
|
||||
run: bun run check:adapters
|
||||
- name: Desktop lint, tests, and build
|
||||
run: bun run check:desktop
|
||||
- name: Electron host checks
|
||||
run: bun run check:electron
|
||||
- name: Persistence upgrade contracts
|
||||
run: bun run check:persistence-upgrade
|
||||
- name: Quarantine governance
|
||||
run: bun run check:quarantine
|
||||
- name: Coverage ratchet
|
||||
if: ${{ !inputs.skip_coverage }}
|
||||
env:
|
||||
COVERAGE_BASE_REF: origin/main
|
||||
run: bun run check:coverage
|
||||
|
||||
# Real desktop UI, real permission dialog, mock runtime. Skips with a printed
|
||||
# reason when agent-browser is unavailable on the runner rather than failing
|
||||
# the whole nightly run.
|
||||
- name: Deterministic desktop UI smoke
|
||||
run: bun run check:desktop-ui-smoke
|
||||
|
||||
- name: Upload nightly artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nightly-quality
|
||||
path: |
|
||||
artifacts/agent-flow/
|
||||
artifacts/desktop-ui-smoke/
|
||||
artifacts/coverage/
|
||||
retention-days: 14
|
||||
|
||||
selection-drift:
|
||||
name: selection-drift
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version-file: package.json
|
||||
- name: Install root dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
# A dependency graph that silently stops resolving would quietly downgrade the
|
||||
# PR gate to prefix-only routing, which is the failure this repository already
|
||||
# shipped. Re-prove the graph nightly against the real tree.
|
||||
- name: Module graph health
|
||||
run: bun test ./scripts/pr/module-graph.test.ts
|
||||
- name: Impact report on the full tree
|
||||
run: bun run check:impact --files "$(git ls-files 'src/*' 'desktop/*' 'adapters/*' | head -400 | tr '\n' ',')"
|
||||
@@ -27,6 +27,7 @@ jobs:
|
||||
desktop_native_checks: ${{ steps.policy.outputs.desktop_native_checks }}
|
||||
provider_contract_checks: ${{ steps.policy.outputs.provider_contract_checks }}
|
||||
chat_contract_checks: ${{ steps.policy.outputs.chat_contract_checks }}
|
||||
agent_flow_checks: ${{ steps.policy.outputs.agent_flow_checks }}
|
||||
persistence_checks: ${{ steps.policy.outputs.persistence_checks }}
|
||||
policy_checks: ${{ steps.policy.outputs.policy_checks }}
|
||||
docs_checks: ${{ steps.policy.outputs.docs_checks }}
|
||||
@@ -167,6 +168,30 @@ jobs:
|
||||
- name: Run desktop-server chat contracts
|
||||
run: bun run check:chat-contract
|
||||
|
||||
agent-flow-checks:
|
||||
name: agent-flow-checks
|
||||
needs: scope-plan
|
||||
if: needs.scope-plan.outputs.agent_flow_checks == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version-file: package.json
|
||||
- name: Install root dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Run deterministic agent flow
|
||||
run: bun run check:agent-flow
|
||||
- name: Upload agent flow artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: agent-flow
|
||||
path: artifacts/agent-flow/
|
||||
retention-days: 7
|
||||
|
||||
adapter-checks:
|
||||
name: adapter-checks
|
||||
needs: scope-plan
|
||||
@@ -298,6 +323,7 @@ jobs:
|
||||
- server-checks
|
||||
- provider-contract-checks
|
||||
- chat-contract-checks
|
||||
- agent-flow-checks
|
||||
- adapter-checks
|
||||
- desktop-native-checks
|
||||
- persistence-checks
|
||||
@@ -341,6 +367,7 @@ jobs:
|
||||
require_selected "server-checks" "${{ needs.scope-plan.outputs.server_checks }}" "${{ needs.server-checks.result }}"
|
||||
require_selected "provider-contract-checks" "${{ needs.scope-plan.outputs.provider_contract_checks }}" "${{ needs.provider-contract-checks.result }}"
|
||||
require_selected "chat-contract-checks" "${{ needs.scope-plan.outputs.chat_contract_checks }}" "${{ needs.chat-contract-checks.result }}"
|
||||
require_selected "agent-flow-checks" "${{ needs.scope-plan.outputs.agent_flow_checks }}" "${{ needs.agent-flow-checks.result }}"
|
||||
require_selected "adapter-checks" "${{ needs.scope-plan.outputs.adapter_checks }}" "${{ needs.adapter-checks.result }}"
|
||||
require_selected "desktop-native-checks" "${{ needs.scope-plan.outputs.desktop_native_checks }}" "${{ needs.desktop-native-checks.result }}"
|
||||
require_selected "persistence-checks" "${{ needs.scope-plan.outputs.persistence_checks }}" "${{ needs.persistence-checks.result }}"
|
||||
|
||||
Reference in New Issue
Block a user