test-driven-development
OBobra/superpowers298k2,631 new stars in the last 7 days
Use when 把任何批次的改动发到 Prismer 测试环境(test.docbrew.cn / APP_ENV=test),或听到「发测试 / 发 test / 上测试环境 / deploy test / 打 ali-k8s-test tag」。涉及 develop 部署、test 迁移通道、runner 节流时必读。
develop 是测试环境的唯一常规通道;ali-k8s-test-* tag 是紧急通道。
违反字面规则就是违反规则本意——不存在「这次情况特殊」。
npm run check 只覆盖前两件,本地绿≠CI 绿):
npx eslint . --max-warnings 3591(warnings 棘轮,随债清偿下调;新代码零新警告)npx tsc --noEmit 0 错npm run test:sandbox:node(node:test sandbox 套件)npm run acs:e2e-smoke:dry-runnpm run test:unit(vitest 根套件)与本批自带的新测试git fetch origin 后 git rev-parse develop origin/develop 两值相等(本地 develop 不滞后)。⚠️ 本地 develop 检出于宿主工作树 /Users/prismer/workspace/pcrefactor/prismercloud——本工作树不能 checkout develop,须在宿主目录 git pull --ff-onlygit rev-list --first-parent origin/develop | grep -qx "$(git merge-base <工作分支> origin/develop)" 出口 0 才合格。2026-09-07 owner 裁决:拓扑形状就是规范面,撤销此前的「内容等价」豁免——tree 无差也不行(实证:avatar 波基点 4bc4b4293 在第二父线=不合格;样例 merge823 第二波基点 9f82c85e3 是第一父线 merge 节点=合格)。不合格 → 从 origin/develop 新切分支,把未并 commits cherry-pick 过去(见下节「切出」)git rev-list --count origin/develop..<工作分支> 输出 = 本批预期 commit 数(防止把并行在飞/不明内容夹带进 MR)src/im/sql/ 与 test 账本。有 pending → 走下方迁移通道,先迁后发;无 → 汇报里显式写「本批无迁移」。src/app/workspace/** 改动 + 桌面重建义务)sha=<源分支 HEAD>(项目开了防漂移校验)ali_k8s_deploy_test(check 阶段全量跑)。禁止为快直打 tag。合并成功后立即执行本地 develop 同步(不是下次发版的起点动作):宿主工作树 /Users/prismer/workspace/pcrefactor/prismercloud 里 git fetch origin && git merge --ff-only origin/develop,贴 git rev-parse develop origin/develop 双值相等输出。⚠️ 2026-09-07 违例记录:连续两轮只操作远端 develop、本地 develop 滞后一个 merge 才被发现——本地/远端视图收敛是每次 merge 的收尾义务。/tmp/<release-name>/ 并在汇报中引用。规范最小单元形状(样例 9f82c85e3 → 51eeb3ad8,2026-08-27 merge823 波):
* <merge> Merge branch 'feature/X' into 'develop'
|\
| * 7±3 个主题聚焦 commits(test+fix/feat 混排,一波一个主题)
|/
* <上一个 merge 节点> ← develop 是一条 merge 直线
scripts/ops/prismer-branch-discipline.sh sync <长期分支>(ff develop → rebase 长期分支;基点=新 develop tip)。样例 merge823 连续两波=同一分支名,第二波同步到第一波 merge 节点(9f82c85e3,第一父线)后继续——不是新建分支。新分支名只用于新主题主线。⚠️ 2026-09-07 违例记录:auth 503 修复为绕开并行会话占用,新开 feature/auth-hydration-503 + 临时 worktree cherry-pick——违反单长期分支纪律(内容经 MR !165 合法入 develop 不追回;教训:并行占用→等安静 sync 长期分支,不另立门户)。fix/*(迁移/热修)用完必删(解除 API 保护 → 删远端 → 删本地)。无 sync 的连续同名 merge 是僵尸信号(merge 次数应=波次数,每波前都有 sync)。git worktree list 逐个核对)与 lint-staged stash;⑤切回工作分支确认 git status clean(并行会话的在飞文件只列不碰)。reading initial communication packet 断连)——不要在本地跑 sync。fix/<name>-test-migration 分支(指向同内容)→ 先 API 加保护(Maintainers/40)→ 后 push / API 建管线。顺序反了管线拿不到受保护 NACOS 变量,须取消重建。test_migration_preflight(dry-run,核对 pending 清单与预期一致)→ test_migration_apply。INFORMATION_SCHEMA.CHECK_CONSTRAINTS。写迁移自问「PolarDB 上成立吗」(scripts/ops/README-test-migration-pitfalls.md)。仅当 owner 原话授权走紧急通道:tag ali-k8s-test-YYYYMMDD-v<X.Y.Z>(X.Y.Z = cat /VERSION,同版本重发加 -rN),打在 develop merge 后的 commit 上。迁移照常前置、节流照常执行、事后必须补 develop/MR 正规化。汇报引用 owner 授权原文。
注意:tag 管线不跑 check 阶段($CI_COMMIT_TAG → when: never)——紧急通道绕过的不只是可见性,还有 eslint 棘轮/t0/runtime 全部质量门(2026-09-04 实测:tag 通道放行的内容在 develop 通道 check 阶段 6 红 + 14 warnings 超棘轮)。事后正规化 MR 会把这些全数暴露,欠的检查终归要还。
| 借口 | 现实 |
|---|---|
| 「CLAUDE.md 表里 tag 也是发版路径」 | 表里 tag 行是紧急/受控通道;ali_k8s_deploy_test 的 develop 规则才是常规。 |
| 「用户说发,我就发」 | 用户授权的是发版动作,不是豁免流程;拿授权当豁免=越权。 |
| 「管线绿了=发版成功」 | 管线绿只是构建部署绿;develop/MR/可见性是发版义务的一部分。tag 管线绿更弱——它连 check 阶段都没跑。 |
| 「迁移我走了受控通道,流程就没问题」 | 迁移通道与发版通道独立记账,一个合规抵不了另一个越权。 |
| 「MR 描述义务太重,先发后补」 | 描述义务是 owner 的审计面;缺了它这次发版不可审计。 |
| 「tag 不动共享分支,更轻」 | 「轻」正是它被定为紧急通道的原因——绕过了所有人的可见性。 |
| 「本地 npm run check 绿了」 | 本地门 ≠ CI check 门:CI 还跑 sandbox node 套件、acs dry-run、t0 三包、runtime 套件与 warnings 棘轮。本地必须跑等价四件套。 |
波次含 sdk/prismer/**(daemon/runtime 源)变更时,cloud 部署不携带 runtime——daemon 拉的是签名 bundle(OTA)。两条通道独立记账:
| 通道 | 触发 | 产物 | 覆盖 |
|---|---|---|---|
| cloud | develop merge → ali_k8s_deploy_test | 容器镜像 | Next.js + in-process IM |
| runtime | tag runtime-test-YYYYMMDD-vX.Y.Z → pack_runtime_bundle | 签名 bundle 上传 + im_runtime_releases 行(status=draft) | daemon/agent pod OTA |
ali-k8s-test-* tag 不触发 pack_runtime_bundle(CI only: 清单实证)——ACK cloud 发版与 runtime 打包是两个 tag 轴。promote_test_runtime_release(manual,需 RUNTIME_RELEASE_APPROVAL_ID,artifact 来自 pack)——draft 对在跑 fleet 零影响,promote 才是生效点。无 owner 原话授权不得代点/代建 tag。git diff $(git merge-base <分支> origin/develop) origin/develop --stat -- sdk/prismer/src 非空 = 有未走 runtime 通道的 daemon 变更(cloud 已发新、daemon 仍旧 = 版本倾斜;本项目缺 protocolVersion 协商,见 daemon version skew 教训)。build_sandbox_image manual 挂 ali-k8s-test/prod tag——仅当波次动了镜像内容(native floor / 系统工具;JS 插件模块不进 image fingerprint)才手动点。src/app/workspace/** / AppProvider 改动 → renderer 重建义务(npm run dev:desktop:renderer);桌面 shell OTA 是独立 desktop-test-* tag 轴,本仓不发。POST /projects/:id/pipeline JSON body 带 variables:[{key,value}] 建新管线(pipeline 级变量)→ 等 pack 成功 → POST /jobs/:id/play 点 promote(继承管线变量)。不要再手点 UI——UI 里忘了填变量就白烧一次 job。play 只对 manual 状态有效;failed job 再 play = 400 Unplayable Job;retry 不带新变量。form-urlencoded 的 variables[][key] 不会被接受(job 起来但变量空,test -n 秒败)——只用 JSON body。RUNTIME_RELEASE_APPROVAL_ID 是自由格式审计串(任意非空有意义标识),记录在 promote 动作上;不是某个注册表 id。/api/runtime/update/bundle/:version OTA 拉取。runtime_rollout_approval CI job(fix/* 手动)在 ci-home 上一步做完:铸 admin 身份([email protected],Nacos test JWT_SECRET + 公网端点 DATABASE_URL 重拼)→ 锚点 work_item 任务(审批必须挂 conversationId/taskId;工作区三级解析:显式 > 名下首个 > 新建 ops-anchor team)→ POST /api/im/approvals(category=ota_rollout + metadata.target 四字段:channel/version/sha256/storageKey,buildContentAddressedRuntimeStorageKey 计算)→ POST decision approve(决定物化,comment 留痕 owner 授权)→ DELETE 锚点任务 → 下载 pack artifact(JOB-TOKEN,job id 指 pack 成功那次)→ publish-daemon-runtime-release.ts --promote-existing --status=ga --approval-id=<id>(前置双 prisma generate;resolve_daemon_release_database_url 锚点给 DB)。id 全程 shell 变量 + 0600 文件,不出 job 不进 artifact(安全复审要求)。test_api_regression CI job 同法:铸 session JWT(mintSessionJwt 全量 claim,test-identity 最小 JWT 会被 apiGuard 拒)→ POST /api/keys 建一次性 key → test-all-apis --env test → DELETE 吊销。curl 全部 --http1.1(CI→test 域 HTTP/2 流 PROTOCOL_ERROR 断连,实测)。build_sandbox_base_image(tag sandbox-image-base-v<N>)产出 SANDBOX_BASE_IMAGE=repo@sha256:<digest>(job 日志/base.env artifact);build_sandbox_image(tag sandbox-image-floor-v<N>)无 needs,必须把该 digest 作为管线变量传入(v29/v30 历史即如此)。SANDBOX_BASE_IMAGE= 行)→ POST /pipeline ref=sandbox-image-floor-v<N> + variables[SANDBOX_BASE_IMAGE] → play。git log --since=<上次 floor 构建日> -- infra/sandbox-image/ 非空 = 冻结镜像落后于 image 源,需新 floor。image-pin.yaml canonical 抬升(sandbox:v<N>→v<N+1>)commit 走 develop;否则 verify_sandbox_image preflight 会在下一波 deploy 拦下「pin 指向不存在的镜像」(delayed ImagePullBackOff 防护)。desktop-test-pack-YYYYMMDD-vX.Y.Z tag 默认是 CI dry-run;真发布要触发时带受保护/手动变量 DESKTOP_TEST_REAL_PUBLISH=1(内部测试可再加 DESKTOP_TEST_SKIP_NOTARIZE=1)。app 版本取 /VERSION,与触发 tag 无关。process.env(如 ZHIPU_MODEL)——依赖 env 的测试必须显式管理并双向断言,否则本地绿 CI 红。expiresAt/绝对日期的测试会隔夜老化(4783 绿→4808 红即此因);fixture 一律相对时间。ORDER BY <ts> DESC LIMIT 1 无 tie-break 在快机器上必现 flaky——加 rowid DESC。git status 逐文件核对。npx eslint . --max-warnings <ratchet> + npx tsc --noEmit + npm run test:sandbox:node + npm run acs:e2e-smoke:dry-run + npm run test:unit。第五件(按改动面):动了 sdk/cloud/catalog/** 或 skill 内容/ops 脚本,必须加跑 npx vitest run scripts/__tests__/(catalog-source-contract 等钉 sha256 清单的 T0 合同面在 vitest 根套件之外——2026-09-08 实证:pkf-writing 内容变更漏跑,check_t0 拦下重走一轮)。git -C <宿主> branch --show-current。2026-09-08 实况:宿主检出的是 release/v2.2.55,本地 已无 develop 分支引用(git rev-parse develop 未知修订)——盲跑 runbook 的 merge --ff-only origin/develop 把 release 分支快进了(已 reset --keep <原值> 复位,untracked 无损)。本地无 develop 引用时该义务即作废:origin/develop 是唯一真相,绝不 ff 当前碰巧检出的分支。glab mr create --source-branch X --target-branch develop --title … --description …;merge 必须 glab mr merge <n> --sha "$(glab api projects/:id/merge_requests/<n> | jq -r .sha)" --yes(防漂移校验);节流 glab api -X POST projects/:id/pipelines/<id>/cancel;cli 在 /opt/homebrew/bin/glab。sdk/prismer/src 变更,cloud deploy 后 daemon fleet 仍旧 bundle(无 protocolVersion 协商的版本倾斜加深的既有状态)——pack+promote 是 HUMAN 门,无 owner 原话授权不得代点,只能在汇报里显式提问。fix/* 再补保护ali-k8s-test-* 就打 tag源头 = sdk/apc/skills/releasing-test/SKILL.md(2026-09-07 归入 apc,随仓库版本控制);.claude/skills/ 为 agent 运行时安装副本,改源头后同步复制。
OBobra/superpowers298k2,631 new stars in the last 7 days
MAmattpocock/skills288k10,178 new stars in the last 7 days
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
Audit accessibility on Web, iOS, and Android to meet WCAG 2.2, with keyboard navigation and screen-reader support.
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
FIfirecrawl/firecrawl191k2,010 new stars in the last 7 days