test(ci): 第6刀 — CI gate 补全(覆盖率闸 A1 + 集成测试 job A2)
A 类「闸的完整性」:
- A1 覆盖率闸(防断崖,非追高):
· go-server job 加 -coverprofile,host 侧解析 total,< 30% 失败(当前 34.9%)。
· flutter-client job 加 --coverage,host 侧 awk 解析 lcov,< 28% 失败(当前 32.7%)。
阈值留 ~5% 缓冲,只拦回归断崖,不卡日常波动。
- A2 集成测试进 CI(新 go-integration job,Job 10):
真 mysql:8/redis 经 testcontainers 跑 -tags integration(跨库可移植/按租户
记账/配额/兑换/节点生命周期/migrate·时区——sqlite 单测覆盖不到的真库行为)。
· 在 host-mode runner 宿主机直接跑 go(不套 golang 容器):testcontainers 要真
docker,DooD 在 Docker Desktop(mac)上网络不通;依赖宿主 go + docker。
· -p 1 串行:一次只起一个 mysql 容器,避免并发压垮 Docker Desktop。
covers/ 覆盖率产物入 .gitignore。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+32
-5
@@ -74,12 +74,16 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: flutter analyze + test (unit/widget)
|
||||
- name: flutter analyze + test + coverage
|
||||
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"
|
||||
bash -c "flutter pub get && flutter analyze --no-fatal-infos && flutter test --coverage test/unit test/widget test/contract"
|
||||
# 覆盖率闸(host 侧解析 lcov):防断崖,低于阈值即失败。
|
||||
COV=$(awk -F: '/^LF:/{f+=$2} /^LH:/{h+=$2} END{if(f>0)printf "%.1f",h/f*100}' client/coverage/lcov.info)
|
||||
echo "flutter 行覆盖 ${COV}%"
|
||||
awk -v c="$COV" 'BEGIN{ if(c+0 < 28){ print "❌ flutter 覆盖率 "c"% < 阈值 28%"; exit 1 } print "✅ flutter 覆盖率 "c"% ≥ 28%" }'
|
||||
|
||||
# ── Job 5: Portable SQL Scan (支柱 3:双库可移植)─────────────────────────
|
||||
# server Go 运行时查询不得含 MySQL 专属构造(同一份 SQL 要跑 mysql 与 sqlite)。
|
||||
@@ -113,7 +117,7 @@ jobs:
|
||||
|
||||
# ── Job 7: Go 服务端(build + test:含契约快照 + sqlite 真库,跳过 integration)──
|
||||
# 此前 server 测试未进 CI;契约快照(支柱 2)等需在此守门。integration 测试走
|
||||
# -tags integration(需 docker 起 mysql/redis),不在本 job,由 run_mysql_test.sh 手动跑。
|
||||
# -tags integration(需 docker 起 mysql/redis),见 go-integration job。
|
||||
go-server:
|
||||
name: Go — build + test
|
||||
runs-on: nas
|
||||
@@ -121,12 +125,16 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: go build + vet + test (non-integration)
|
||||
- name: go build + vet + test + coverage
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v "$PWD/server:/app" -w /app \
|
||||
golang:1.25 \
|
||||
bash -c "go build ./... && go vet ./... && go test ./..."
|
||||
bash -c "go build ./... && go vet ./... && go test -coverprofile=cover.out ./... && go tool cover -func=cover.out > coverage.txt"
|
||||
tail -1 server/coverage.txt
|
||||
# 覆盖率闸(host 侧解析,避开容器引号转义):防断崖,低于阈值即失败。
|
||||
COV=$(grep '^total:' server/coverage.txt | grep -oE '[0-9]+\.[0-9]+')
|
||||
awk -v c="$COV" 'BEGIN{ if(c+0 < 30){ print "❌ Go 覆盖率 "c"% < 阈值 30%"; exit 1 } print "✅ Go 覆盖率 "c"% ≥ 30%" }'
|
||||
|
||||
# ── Job 8: E2E Smoke (L4 进程级端到端,含 gRPC 全链路)───────────────────
|
||||
# 真起打包的 server 二进制(sqlite 临时库 + 内嵌 miniredis,无需 docker-in-docker)
|
||||
@@ -146,6 +154,25 @@ jobs:
|
||||
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 10: Go 集成测试 (L2:真 mysql8/redis 经 testcontainers)──────────
|
||||
# 跨库可移植(支柱 3)+ 按租户流量记账(usage)+ 配额(devices)+ 兑换(codes)+
|
||||
# 节点生命周期(nodes)+ migrate/时区(store)的真库行为,sqlite 单测覆盖不到。
|
||||
# 走 -tags integration,testcontainers 自起 mysql:8/redis 容器。
|
||||
# · 在 host-mode runner 的宿主机直接跑 go(不套 golang 容器):testcontainers 要真
|
||||
# docker,DooD 套在容器里在 Docker Desktop(mac)上网络不通。依赖宿主 go + docker。
|
||||
# · -p 1 串行:一次只起一个 mysql 容器,避免并发把 Docker Desktop 压垮/端口资源争用。
|
||||
go-integration:
|
||||
name: Go — integration (mysql/redis testcontainers)
|
||||
runs-on: nas
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: go test -tags integration (宿主 docker + testcontainers)
|
||||
run: |
|
||||
cd server
|
||||
go test -tags integration -count=1 -p 1 ./...
|
||||
|
||||
# ── Job 9: Golden 视觉回归 (L3 子集:components + auth)──────────────────
|
||||
# Linux 权威基线(scripts/update-goldens.sh 生成;mac 渲染不一致故钉死 Linux 容器)。
|
||||
# tablet/desktop-stats golden 与 stats-overhaul 工作区耦合,待其合并后并入本 job。
|
||||
|
||||
@@ -76,3 +76,8 @@ client/test/golden/failures/
|
||||
|
||||
# Inno Setup 编译产物(安装包,本地生成不入库)
|
||||
client/windows/installer/Output/
|
||||
|
||||
# 覆盖率产物(CI 覆盖率闸生成,临时不入库)
|
||||
/server/cover.out
|
||||
/server/coverage.txt
|
||||
/client/coverage/
|
||||
|
||||
Reference in New Issue
Block a user