8.2 KiB
8.2 KiB
P2 CI + 测试基线 — 设计规格
日期:2026-09-30 | 状态:已批准(用户指令:写计划、派子代理、端到端交付、不再提问)
涉及仓库:crearte-server(GitHub 私有)、crearte-deploy(GitHub 私有)、crearte(GitHub 公开)
前置事实:P0/P1/P4/P5 已交付;crearte/.github/workflows/validate.yml 已存在(pull_request 触发,node 24,check + e2e 两 job);后端/部署仓零 CI。
1. 问题定义(ROADMAP 原文拆解)
- 后端/部署仓无 CI → 两仓各建
validate.yml,风格对齐前端现有文件。 - Postgres 集成层静默 skip → 后端 CI 必须有真实 Postgres service,且当且仅当集成测试真的跑了才算绿(skip 在 CI 上下文里视为失败)。
- e2e:stack 全链路 → 真栈 Playwright full-loop 首次进 CI(宿主仓因凭据限制定为 crearte-server,见 2.2 修订)。
2. 范围决策
2.1 crearte-server validate.yml(新文件)
- 触发:
pull_request(paths:src/**、workflow 自身)+push: master。与前端文件同构。 - Job
check(无 DB):gofmt -l空断言 →go vet ./...→go build ./...→go test ./...。pg-gated 在此 job 正常 skip(语义与本地开发一致)。 - Job
integration:GitHubservices: postgres(postgres:17-alpine,与 crearte-deploy 所用镜像一致,user/pass/db = crearte);TEST_DATABASE_URL指向空库——集成测试自带repository.Migrate引导(migrate_test.go:testDBsync.Once + Migrate;service 层 gated 测试也各自 Migrate),所以空库即全量真跑,同时白赚一条"从空库可完整迁移"的每 PR 回归。go test -v -count=1 -p 1 ./...:-p 1必须——各 gated 测试对共享表做TRUNCATE,包间并行(默认并行度)必互相踩踏;-p 1序列化包执行是既有测试写法(不改测试)下唯一的正确姿势。- skip 守卫:
tee落日志后grep 'skipping postgres integration test'命中即 FAIL(pipefail 显式开)。没有守卫,这个 job 退化成 check 的复读机。
- Go 版本:
actions/setup-go@v5+go-version-file: src/go.mod(1.24.1)+cache-dependency-path: src/go.sum。
2.2 真栈 e2e 的宿主仓:放在 crearte-server,不放 crearte(计划阶段勘察后的范围修订)
原稿把 e2e-stack 挂进 crearte CI——勘察后不可行:XingfenD/crearte-server 是私有仓(GitHub API 404 验证),公开仓的 workflow 用默认 token 无法 checkout 它;本机无 GitHub API 凭据,不能自助签发 PAT。反向则天然可行:server 的 workflow checkout 公开的 crearte 无需任何 token。
修订后的布局:
- e2e-stack job 落进 crearte-server 的 validate.yml:双 checkout(server=默认 token,crearte=公开无 token,均带 path)+ setup-go(go-version-file 指向 server 仓内 go.mod)+ node 24 + playwright chromium;env
CREARTE_STACK_BACKEND_REF: ${{ github.sha }}——直接测 PR 那个后端 commit,信号强于拉 master(原布局只能测 master 后端)。路径适配:两仓 path 必须使dirname(REPO_ROOT)/crearte-server命中兄弟仓(即path: crearte与path: crearte-server同级);脚本用$BACKEND/.git的 origin 去 fetch SHA(GitHub 允许 fetch 任意 commit SHA)。working-directory 全部crearte/src。 - crearte 仓的改动缩小为:
e2e-stack.sh支持CREARTE_STACK_GO(显式指定 go 二进制,解 runner 上/usr/local/go/bin/go版本地板假绿隐患;不设即旧逻辑,本地零变化)与CREARTE_STACK_REQUIRED(置 1 时栈起不来直接 exit 1,封死“CI 里静默 skip=假绿”通道;不设即本地 skip 模式);validate.yml补push: branches: [master]触发(既有两 job 不动);CHANGELOG 0.17.0。server CI 的 e2e-stack job 设这两个 env。 - full-loop 假绿风险由 REQUIRED 模式从根上封死:webServer 命令非零退出 → playwright job 红。无需 JSON 报告器断言,不赌 reporter 输出格式。
- 已接受的限制(如实记录):纯前端 PR(只动 crearte)不再有真栈 e2e 信号,改由 server 侧每次 PR/push 带最新 crearte master 补位(前端变更合入后即被覆盖);若 owner 日后在 crearte 仓配
STACK_BACKEND_TOKENsecret,可镜像同构 job 回 crearte——列为可选增强,不阻塞交付。
2.3 crearte-deploy validate.yml(新文件)
- 无编译产物,CI 价值 = compose 健全性:
docker compose --profile dev --profile prod --profile full config -q(:?守卫变量注入假值,另测缺POSTGRES_PASSWORD必须非零退出,证明守卫没被无声旁路)。 config不校验 bind 路径存在性,故../crearte挂载在单仓 checkout 下也能过——如实记录:单仓 config ≠ 可部署;跨仓挂载完整性仍由本 monorepo 演练承担(P1 已证)。deploy 仓 README「单仓 clone」小节加一行指向本 spec,防误读。- deploy 的 AGENTS.md「no host-run workflows」指本机别跑 npm/go;GH Actions 跑
compose config不落任何宿主机进程,不违反。 - CHANGELOG 新 patch 条目(双语)。
2.4 全局非目标
- 不做分支保护:无 GitHub API 凭据(
gh缺失、token 库空),owner 在 Settings→Branches 手动开启(server/deploy 必开,crearte 建议开)。写进 spec 交付清单,不进计划任务。 - 不验证 Actions 已启用:私有仓 Actions 可能因计划限制未开/额度耗尽——推送后无 API 可查证。如实交付:计划里把「owner 在 GitHub UI 看 Actions 出现绿勾」列为部署后人工尾巴(与 P5 浏览器验收同类 manual-deferred);本机能验的全验(见 3)。
- 不动 git.yoresee.cc 的 Gitea Actions(内层三仓不在 Gitea)。
- 不重构测试文件(除任务 4 实测证明假绿通道时的最小修复)。
- 不引入 lint(golangci-lint)、不引 codecov。
3. 验证策略(无 GitHub API,全部本地等价模拟)
任务 4 在本机以与 CI job 同构的容器化步骤跑三套:
check:dockergolang:1.24-alpine(GOPROXY 走 goproxy.cn——本机网络事实)四连。integration:postgres:17-alpine容器(端口 5434,全新空库,--add-host=host.docker.internal:host-gateway让测试容器可达)+go test -v -count=1 -p 1 ./...+ skip 守卫。跑两遍:第二遍证明 Migrate 幂等下的共存。e2e:stack:在 monorepo 真实布局(兄弟仓天然就位、宿主 go 1.26.8)跑npm run e2e:stack,断言日志出现[stack] ready:(真绿非假绿),另跑一次「无 docker 假绿反向验证」用 PATH 屏蔽 docker 令stack_ok=0,确认 SKIP 模式在报告中显式可见。- deploy config 正反两路。
推送本身(git push 成功)是 Actions 接收 workflow 的充分条件;job 结果查证为人工尾巴。
4. 交付物清单
| 仓库 | 文件 | 动作 |
|---|---|---|
| crearte | src/scripts/e2e-stack.sh |
CREARTE_STACK_GO + CREARTE_STACK_REQUIRED 两个 env 开关 |
| crearte | .github/workflows/validate.yml、docs/CHANGELOG.md |
push:master 触发;0.16.1 |
| crearte-server | .github/workflows/validate.yml、docs/CHANGELOG.md |
check + integration + e2e-stack 三 job;0.11.1 |
| crearte-deploy | .github/workflows/validate.yml、docs/CHANGELOG.md、README.md |
compose config 正反两路;0.5.1 |
| wrapper | 本 spec + 计划、ROADMAP P2 行、CHANGELOG 0.2.4 | 收尾 |
| GitHub UI | Actions 启用确认 + 分支保护 | owner 手动(见 2.4) |
5. 验收标准(Definition of Done)
- 三仓
.github/workflows/validate.yml合入各自 master 并推送;分支删除。 - 任务 4 四组模拟全绿且证据留档(
.superpowers/sdd/p2-task-4-report.md):integration 首跑必须含RUN Test…Postgres/真跑字样、零 "skipping postgres integration test"。 e2e:stack真栈一跑[stack] ready:出现、full-loop 用例计数 >0 且全过;CREARTE_STACK_REQUIRED=1反路在栈起不来时 exit 1(不静默 skip)。- ROADMAP P2 → 完成(三 hash);wrapper CHANGELOG 0.2.4;人工尾巴(Actions 查证、分支保护)在 ROADMAP 行或 spec 有明确记载。