name: ci-pangolin # 触发条件:deploy/ 或 design/ 或 client/ 或 server/ 或 ci/ 变更时,以及所有向 main 的 PR on: push: branches: [main] paths: - 'deploy/**' - 'design/**' - 'client/**' - 'server/**' - 'ci/**' - '.gitea/workflows/ci.yml' pull_request: branches: [main] workflow_dispatch: jobs: # ── Job 1: Lint (shellcheck) ───────────────────────────────────────────── lint: name: Lint — shellcheck runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: shellcheck 节点脚本(bootstrap + single-node) run: | docker run --rm \ -v "$PWD/deploy:/mnt/deploy:ro" \ koalaman/shellcheck:stable \ shellcheck -S warning \ /mnt/deploy/bootstrap/init.sh \ /mnt/deploy/bootstrap/monitor/pangolin-monitor.sh \ /mnt/deploy/bootstrap/monitor/deadman-watch.sh \ /mnt/deploy/single-node/deploy.sh # ── Job 2: OpenAPI Sync Check ──────────────────────────────────────────── openapi-check: name: OpenAPI Sync Check runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 # openapi-spec-validator 是纯 Python、无外部依赖,校验 OAS 3.0 结构合法性。 - name: lint design/server/openapi.yaml run: | docker run --rm \ -v "$PWD/design/server:/spec:ro" \ python:3.12-alpine \ sh -c "pip install openapi-spec-validator --quiet && \ python -m openapi_spec_validator /spec/openapi.yaml" # ── Job 3: Redline Word Scan (脱敏) ────────────────────────────────────── redline-scan: name: Redline Scan — 脱敏 (UI 文案) runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: scan UI text resources for prohibited words run: bash ci/scan-redline.sh # ── Job 4: Flutter 客户端(分析 + 单测/组件测试)──────────────────────── flutter-client: name: Flutter — analyze + test runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: flutter analyze + test (unit/widget) run: | docker run --rm \ -v "$PWD/client:/app" -w /app \ ghcr.io/cirruslabs/flutter:stable \ bash -c "flutter pub get && flutter analyze --no-fatal-infos && flutter test test/unit test/widget test/contract" # ── Job 5: Portable SQL Scan (支柱 3:双库可移植)───────────────────────── # server Go 运行时查询不得含 MySQL 专属构造(同一份 SQL 要跑 mysql 与 sqlite)。 # 规则与豁免见 ci/scan-portable-sql.sh 头注 + docs/dev-conventions.html 支柱 3。 portable-sql-scan: name: Portable SQL — 可移植性 (mysql/sqlite) runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: scan server Go runtime SQL for MySQL-specific constructs run: bash ci/scan-portable-sql.sh # ── Job 6: Codegen Drift (支柱 2:token 单源不漂移)────────────────────── # 重新生成 client/lib/pangolin_tokens.gen.dart,与已提交版本不一致即失败 # (改了 design/colors_and_type.css 没重生成,或手改了生成物)。 codegen-drift: name: Codegen Drift — token 生成物未漂移 runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: regenerate flutter tokens & assert no drift run: | docker run --rm \ -v "$PWD:/repo" -w /repo \ node:20 \ bash ci/check-codegen-drift.sh # ── Job 7: Go 服务端(build + test:含契约快照 + sqlite 真库,跳过 integration)── # 此前 server 测试未进 CI;契约快照(支柱 2)等需在此守门。integration 测试走 # -tags integration(需 docker 起 mysql/redis),不在本 job,由 run_mysql_test.sh 手动跑。 go-server: name: Go — build + test runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: go build + test (non-integration) run: | docker run --rm \ -v "$PWD/server:/app" -w /app \ golang:1.25 \ bash -c "go build ./... && go test ./..." # ── Job 8: E2E Smoke (L4 进程级端到端,含 gRPC 全链路)─────────────────── # 真起打包的 server 二进制(sqlite 临时库 + 内嵌 miniredis,无需 docker-in-docker) # → enroll(mTLS)→ ReportUsage 注入用量 → /v1/usage 断言统计真入库真读出。 # 详见 scripts/e2e-smoke.sh + server/test/e2e/。 e2e-smoke: name: E2E Smoke — L4 进程级端到端 runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: 进程级端到端冒烟 (server 二进制 + miniredis + gRPC 全链路) run: | docker run --rm \ -v "$PWD:/repo" -w /repo \ golang:1.25 \ bash -c "apt-get update -qq && apt-get install -y -qq openssl curl python3 >/dev/null 2>&1 && bash scripts/e2e-smoke.sh" # ── Job 9: Golden 视觉回归 (L3 子集:components + auth)────────────────── # Linux 权威基线(scripts/update-goldens.sh 生成;mac 渲染不一致故钉死 Linux 容器)。 # tablet/desktop-stats golden 与 stats-overhaul 工作区耦合,待其合并后并入本 job。 golden: name: Golden — 视觉回归 (components + auth) runs-on: nas steps: - name: Checkout uses: actions/checkout@v4 - name: flutter test golden (Linux 权威基线) run: | docker run --rm \ -v "$PWD/client:/app" -w /app \ ghcr.io/cirruslabs/flutter:stable \ bash -c "flutter pub get && flutter test test/golden/components_golden_test.dart test/golden/auth_redesign_golden_test.dart"