feat: enforce Guanghu-native HoloLake runtime laws

This commit is contained in:
冰朔 2026-08-04 23:11:25 +08:00
commit 67e6fcdd38
57 changed files with 1765 additions and 1504 deletions

View file

@ -1,133 +1,15 @@
# CI/CD Setup
# HoloLake 原生工程流水线
## GitHub Actions Workflow
流水线执行 HoloLake 已登记的光湖原生工程门,不调用外部评分服务,也不把
托管平台的状态当作光湖事实。
Il workflow `ci.yml` esegue i seguenti check automatici:
## 当前执行顺序
### 1. Tests
- Frontend: `pnpm test`
- Rust backend: `cargo test`
1. 回读产品工程档案和固定的 `REPO-012` 协议注册表提交。
2. 验证第三方评分规则没有重新进入现行权威面。
3. 验证人格系统输入、类型化输出、能力登记和证据回执合同。
4. 运行产品单元、集成、格式、静态检查、脚本语法和构建门。
5. 对精确提交与源码树汇总 `GHNQG_PASS_100``GHNQG_FAIL_0`
### 2. Test Coverage
- Frontend: vitest con coverage reporting
- Upload automatico su Codecov dai report LCOV frontend + Rust
- Threshold configurabile in `vitest.config.ts`
### 3. Code Health (CodeScene)
- Delta analysis su ogni PR/push
- Fail se il code health diminuisce
- Richiede secrets configurati (vedi sotto)
### 4. Documentation Check
- Verifica che se cambia codice in `src/` o `src-tauri/`, anche `docs/` viene aggiornato
- **Warning only** — non blocca il merge, solo un reminder
- Skip con `[skip docs]` nel commit message
- Aggiorna docs solo se la modifica invalida architettura/astrazioni/design già documentati
### 5. Lint & Format
- ESLint per frontend
- Clippy + rustfmt per Rust
## Setup Required
### CodeScene Secrets
Aggiungi questi secrets nel repository GitHub (Settings → Secrets → Actions):
```
CODESCENE_TOKEN=<your-codescene-pat>
CODESCENE_PROJECT_ID=<your-project-id>
```
Il PAT di CodeScene è lo stesso che usi localmente (~/.codescene/token).
Il project ID lo trovi nella dashboard CodeScene.
### Codecov Setup
- Installa/attiva il repo in Codecov una volta sola tramite GitHub App / import del repository.
- Nessun `CODECOV_TOKEN` richiesto in GitHub Actions: `ci.yml` usa OIDC (`id-token: write` + `use_oidc: true`).
- Il workflow carica `coverage/lcov.info` (Vitest) e `coverage/rust.lcov` (cargo-llvm-cov).
- L'action Codecov resta con integrity validation attiva. Se Codecov ruota la chiave GPG del CLI, aggiorna il pin dell'action invece di usare `skip_validation`.
### Telemetry Secrets For Release Builds
Aggiungi anche questi secrets per i workflow `release.yml` e `release-stable.yml`:
```
VITE_SENTRY_DSN=<frontend sentry dsn>
SENTRY_DSN=<same dsn for rust/native crash reporting>
VITE_POSTHOG_KEY=<posthog project api key>
VITE_POSTHOG_HOST=https://eu.i.posthog.com
```
Senza questi valori, i build distribuiti possono mantenere i toggle telemetry nelle Settings ma non inizializzare davvero PostHog/Sentry.
### Windows Authenticode Secrets For Release Builds
Windows alpha e stable release builds usano sempre le firme Tauri updater. Se i secret Authenticode sono presenti, il workflow firma anche gli installer Windows e verifica le firme; se mancano, emette un warning e pubblica gli artifact Windows senza Authenticode finche' il certificato non e' pronto.
```
WINDOWS_CODE_SIGNING_CERTIFICATE=<base64-encoded pfx>
WINDOWS_CODE_SIGNING_CERTIFICATE_PASSWORD=<pfx password>
```
Opzionale:
```
WINDOWS_CODE_SIGNING_CERTIFICATE_THUMBPRINT=<expected thumbprint>
WINDOWS_CODE_SIGNING_TIMESTAMP_URL=https://timestamp.digicert.com
```
Il certificato deve essere un certificato di code signing trusted; un certificato self-signed non e' adatto per i release artifact pubblici.
### Coverage Thresholds
Configura in `vitest.config.ts`:
```typescript
export default defineConfig({
test: {
coverage: {
lines: 80,
functions: 80,
branches: 80,
statements: 80,
// Fail CI se sotto threshold
thresholds: {
lines: 80,
functions: 80,
branches: 80,
statements: 80
}
}
}
})
```
## Local Testing
Prima di pushare, puoi testare localmente:
```bash
# Run all tests
pnpm test && cargo test
# Check coverage
pnpm test:coverage
# Lint
pnpm lint
cargo clippy
cargo fmt --check
# CodeScene (local)
codescene delta-analysis --base-revision origin/main
```
## Workflow Triggers
- **Push**: su `main`
- **Pull Request**: verso `main`
- **Manuale**: `workflow_dispatch`
Nota: l'upload a Codecov gira su push a `main` e sulle PR dello stesso repository. Le PR da fork saltano l'upload per evitare problemi di permessi OIDC.
## Status Checks
Tutti i check devono passare prima di poter fare merge.
Se un check fallisce, vedrai il dettaglio nei logs di GitHub Actions.
流水线通过只证明该源码树完成了已声明的工程门,不证明已经上传、部署、在线、
出生或取得服务器权限。部署与运行状态必须由目标节点自己的回执独立证明。

View file

@ -25,7 +25,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for CodeScene
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
@ -72,43 +72,8 @@ jobs:
if: steps.docs-changes.outputs.should-build == 'true'
run: pnpm docs:build
# ── 1. Code Health (CodeScene — Hotspot + Average Code Health gates) ──
# Enforces minimum floors on BOTH hotspot and average code health.
# Thresholds come from .codescene-thresholds so CI and local hooks match.
- name: Code Health gates
env:
CODESCENE_PAT: ${{ secrets.CODESCENE_PAT }}
CODESCENE_PROJECT_ID: ${{ secrets.CODESCENE_PROJECT_ID }}
run: |
HOTSPOT_THRESHOLD=$(grep '^HOTSPOT_THRESHOLD=' .codescene-thresholds | cut -d= -f2)
AVERAGE_THRESHOLD=$(grep '^AVERAGE_THRESHOLD=' .codescene-thresholds | cut -d= -f2)
API_RESPONSE=$(curl -sf \
-H "Authorization: Bearer $CODESCENE_PAT" \
-H "Accept: application/json" \
"https://api.codescene.io/v2/projects/$CODESCENE_PROJECT_ID")
HOTSPOT_SCORE=$(echo "$API_RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['analysis']['hotspot_code_health']['now'])")
AVERAGE_SCORE=$(echo "$API_RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['analysis']['code_health']['now'])")
echo "Hotspot Code Health: $HOTSPOT_SCORE (threshold: $HOTSPOT_THRESHOLD)"
echo "Average Code Health: $AVERAGE_SCORE (threshold: $AVERAGE_THRESHOLD)"
python3 -c "
hotspot = float('$HOTSPOT_SCORE')
average = float('$AVERAGE_SCORE')
ht = float('$HOTSPOT_THRESHOLD')
at = float('$AVERAGE_THRESHOLD')
failed = False
if hotspot < ht:
print(f'❌ Hotspot Code Health {hotspot:.2f} is below threshold {ht}')
failed = True
else:
print(f'✅ Hotspot Code Health {hotspot:.2f} ≥ {ht}')
if average < at:
print(f'❌ Average Code Health {average:.2f} is below threshold {at}')
failed = True
else:
print(f'✅ Average Code Health {average:.2f} ≥ {at}')
if failed:
exit(1)
"
- name: Guanghu native authority contract
run: pnpm test:native-authority && pnpm test:native-core
# ── 2. Documentation check (warning only — does not fail build) ───────
- name: Check docs are updated
@ -133,7 +98,7 @@ jobs:
run: pnpm lint
frontend-tests:
name: Frontend Tests & Coverage
name: Frontend Tests
runs-on: macos-15
steps:
@ -153,25 +118,11 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile
# The coverage command runs the canonical frontend test suite.
- name: Bundle MCP server resources (required by Tauri build)
run: node scripts/bundle-mcp-server.mjs
- name: Frontend tests + coverage (≥70% lines/functions/branches/statements)
run: pnpm test:coverage
# Thresholds configured in vite.config.ts — exits non-zero if coverage drops
- name: Upload frontend coverage to Codecov
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: codecov/codecov-action@5975040f7f7d40edaff8d784b576fd65ae95c073
with:
use_oidc: true
fail_ci_if_error: true
disable_search: true
files: ./coverage/lcov.info
flags: frontend
verbose: true
# OIDC avoids long-lived CODECOV_TOKEN secrets.
- name: Frontend tests
run: pnpm test
rust-quality:
name: Rust Tests & Quality Checks
@ -196,32 +147,11 @@ jobs:
restore-keys: |
${{ runner.os }}-cargo-${{ env.RUST_TARGET_CACHE_VERSION }}-
- name: Install cargo-llvm-cov
- name: Install native coverage executor
uses: taiki-e/install-action@e5de28abeb52d916c5e5875d54b21a9e738b61ec
- name: Rust tests + coverage (≥85% lines)
run: |
mkdir -p coverage
cargo llvm-cov \
--manifest-path src-tauri/Cargo.toml \
--ignore-filename-regex 'lib\.rs|main\.rs|menu\.rs' \
--lcov \
--output-path coverage/rust.lcov \
--fail-under-lines 85
# cargo-llvm-cov exits non-zero if line coverage drops below 85%
# lib.rs/main.rs/menu.rs are Tauri boilerplate -- not meaningfully unit-testable.
- name: Upload Rust coverage to Codecov
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: codecov/codecov-action@5975040f7f7d40edaff8d784b576fd65ae95c073
with:
use_oidc: true
fail_ci_if_error: true
disable_search: true
files: ./coverage/rust.lcov
flags: rust
verbose: true
# OIDC avoids long-lived CODECOV_TOKEN secrets.
- name: Rust tests
run: cargo test --manifest-path src-tauri/Cargo.toml
- name: Clippy (Rust)
run: cargo clippy --manifest-path=src-tauri/Cargo.toml -- -D warnings
@ -229,6 +159,13 @@ jobs:
- name: Format check (Rust)
run: cargo fmt --manifest-path=src-tauri/Cargo.toml -- --check
- name: GLS-0844 HoloLake native quality receipt
run: |
mkdir -p "$RUNNER_TEMP/ghnqg"
bash scripts/run-hololake-native-quality-gate.sh \
"$RUNNER_TEMP/ghnqg/GHNQG-${GITHUB_SHA}.hldp"
grep -Fxq 'result: PASS_100' "$RUNNER_TEMP/ghnqg/GHNQG-${GITHUB_SHA}.hldp"
linux-build:
name: Linux build verification
# Keep the normal push CI lane under the 10-minute target. The release