登记簿、文档与代码注释里的存量字母加数字编号(N-x / S-x / T-x / E-x / A-x / 卡号) 一律改写为语义短语,净删 2,028 处引用;删除基线与待确认、并行分道方案、排期详述、 采集保护收尾 4 篇(内容已并入 docs/任务规划/README 与登记簿)。 门禁机器与三张账同批重打:check_ids.py 新增变更记录行豁免与第二根护栏 undecidable_total_ceiling;check_test_traceability.py 只加 stdout/stderr UTF-8 reconfigure(TC_RE 未动);check_cubemx_survival.py 的 --write 固定 newline=LF; id_registry / id_aliases(+19 条 retired-to-phrase)/ id_known_backlog 重打。 test/ 56 个文件同步 TC 标签语义化,其中 18 个 TU 改了 CHECK / printf 里的标签文字, 是本批唯一改变构建产物的文件集合。 为什么合成一笔、不拆四笔(实测撞闸,非偏好):pre-commit 跑钩子前会 stash 未 staged 部分,拆开后中间提交必然是「新规则 + 旧语料」——实跑可判定 85.15% < 基线 86.00%、 不可判定 1,453 > 上限 1,166,编号门禁直接拦下。编号识别面与它描述的语料只能同码移动。 实跑基线(工作区全量):754 文件 / 8,230 处编号字面量 / 可判定 7,079 = 86.01% (基线 86.0%,容差 0.1pp)/ 不可判定绝对数 1,151(上限 1,166)/ 校验 1-6 错误级 0 / 告警 = 悬空 2(App/algo/freq.c 的 S2,属 §4.4 同号不同义)+ 孤儿 50。 基线从 84.0 抬到 86.0 的理由见 docs/门禁说明/id-check.md §7.6:本批真删了 2,028 处 引用,可判定面随真实内容上升,不是把分母做小。同批新增排除 docs/硬件平台/ 语料,使 识别面少 264 处——芯片手册位号与网表料号不属编号空间(registry 有 excluded_paths_note)。 ⚠ 余量只剩 0.11pp(约 10 处)与绝对数 15 处:把「可判定的引用」改成散文会立刻撞第二 根护栏。另遗留一项:id_aliases 里 retired 的 N / S / T / A 别名没有 scope(U1~U5 有), 今后有人新写一个 A-4,校验 3 不会响,只能靠人,建议下批补 scope。 固件不变证据:115 个 .c/.h 剥注释并归一字符串后与 HEAD 逐字节全等,残留代码差异 0; App / Src / Drivers 的字符串字面量零改动。@build 0 错误 0 警告;40/40 主机套件、2,889 断言全通过;覆盖率 line 89.2% / func 92.6%;pre-commit 48 钩子 --all-files 全绿; check_doc_links --all 通过(176 文档,章节引用无法判定 0);逐字节卫生核过:14 个带 BOM 文件与 HEAD 一致、0 个 CR、0 个 U+FFFD,字符串字面量纯 ASCII。 .cubemx_survival_baseline.json 的 watchdog-module 哈希 56bf27 变 2bb051 属合法: Src/freertos.c 的 USER CODE 区内只有注释文字随编号改写,代码未变。 同批带上体积同码凭证与 RAM 台账行(@build 之后盖戳):RW_IRAM1 79,008 B / 60.3%, RW_CCM 57,376 B / 87.9%,阈值 92%。
远程 CI(Gitea Actions)—— 本目录是唯一入口
适用范围(先读这句,可以省下很多时间) 本仓库的远程 CI 只跑在本机这一台 runner 上:runner 名
win-stm32-ci,装在D:\Docker\act_runner,连的是本机原生 Giteahttp://127.0.0.1:3001。 其他机器、其他项目都不涉及,也不需要配这套东西。日常改代码不需要读本目录:提交前的等价自查是本地门禁,runner 在不在线都照样跑——
& '.venv\Scripts\python.exe' scripts/ci_local.py # L0 静态 + L0b 提交信息 + L0.5 主机单测只有在这三种情况下才需要进来:① 换机/重装后要重新部署 runner;② CI 不出任务或莫名 取消;③ 改
.gitea/workflows/ci.yml本身。
索引
全部内容是一篇文档:远程CI完整指南.md(2026-10-12 由原「环境与部署」
目录下的两篇指南 CI配置指南.md 与 Gitea_Runner部署指南.md 合并而来,两篇均已删除,
去重后为单一来源)。
| 想干什么 | 去看 |
|---|---|
| 先搞清 CI 需要哪三样东西就位、本机拓扑、部署前置清单 | §0 / §0.1 / §0.2 |
| CI 体积门禁现在怎么守(同码凭证强制,「只声明不执行」那处盲区已关闭;gitlint 空转仍在) | §0.0 + §7 排障表"钩子条数对不上"行 |
服务端开启 Actions、DEFAULT_ACTIONS_URL 到底管什么 |
§1(含 §1.2.1,这条最容易搞反) |
下载 / 注册 runner(--instance 用回环、labels 必须精确匹配 runs-on) |
§2.2 |
config.yaml 各字段语义(capacity / timeout / labels / 日志目录…) |
§2.3 |
| 常驻:为什么必须看门狗、不能只起 daemon、也不能做成 Windows 服务 | §2.4 + §3.0 |
runner 装什么软件、为什么变量必须对 SYSTEM 可见、机器级 DTU_* |
§4(§4.1.1~§4.1.3 是三个真坑) |
workflow 位置 / 触发 / 内网拉不到 actions/checkout 的三种处置 |
§5(§5.3 零依赖写法) |
| 两个 job 各自跑哪些步骤、两条 Python 探测链要同序同步 | §5.5 |
| 端到端验证清单、无网页登录时直查 MySQL 核验 | §6 / §6.1 |
出问题了按症状查表(含 0x41301、1053、72h 被杀、.ps1 无 BOM 乱码…) |
§7 |
| 日常维护(改钩子集 / 改 workflow 后要不要动 runner) | §8 |
| 一键自检脚本、最小操作清单 TL;DR | §9 / §10 |
常用命令速查
# 本地等价门禁(不依赖 runner,日常用这个)
& '.venv\Scripts\python.exe' scripts/ci_local.py
# runner 体检(四项:计划任务 / 进程 / Gitea 可达 / 机器级变量)—— 须管理员
& '.\scripts\ci_runner_bootstrap.ps1' -Status
# 干跑:只打印将要写入的启动器与任务对象,不落盘不注册(免管理员)
& '.\scripts\ci_runner_bootstrap.ps1' -DryRun
# 部署 / 修复:写机器级 DTU_* + 生成看门狗启动器 + 注册开机计划任务 + 立即启动(须管理员)
& '.\scripts\ci_runner_bootstrap.ps1' -SetEnv -StartNow
⚠️ 上面三条
ci_runner_bootstrap.ps1是本机运维动作,会改系统计划任务与机器级环境 变量;返回码0x41301是"任务正在运行"、next run为空是开机触发器的正常表现, 都不是故障(详见指南 §3.4)。
✅ 机器侧遗留已清理(2026-10-12):旧方案的
deploy_runner_task.ps1与run_runner.cmd已从D:\Docker\act_runner\删除(它们跑单次 daemon,首次 Declare 失败就永久停摆, 机理见指南 §3.2;check_env.ps1里指向它们的提示也已改指 bootstrap)。 现行部署只有ci_runner_bootstrap.ps1这一条路。
🔴 重跑部署前先知道这条(2026-10-12 实测):
Unregister-ScheduledTask不会带走旧实例 启动的进程。旧看门狗会作为孤儿继续养着它的 daemon,而那个 daemon 占着.runner.lock, 于是新看门狗每 10 秒失败一次(runner file is already locked by another process)—— 而 runner 在网页上照样显示 online,CI 看着正常,任务其实谁也没管。 现在-StartNow会先清掉这些残留进程再启动(约离线几秒),-Status也会报出重复实例。 2026-10-12 已实测收敛:清掉 3 个残留后daemon up: pid … (single instance), 监管链svchost(任务) → 看门狗 → daemon恢复,runner 回 online。
相关文档
- 测试分层与门禁决策(L0~L3 各层由谁把关):
../测试说明/测试开发标准流程.md - workflow 本体:
../../.gitea/workflows/ci.yml - 本地等价脚本:
../../scripts/ci_local.py - runner 机器的工具链环境要求:
../环境与部署/项目部署环境要求.md DTU_*工具路径变量机制:../环境与部署/本地工具路径环境变量方案.md
变更记录
| 日期 | 变更 |
|---|---|
| 2026-10-12 | 🐛 首次真跑出 run:L0.5 成功(10 runner(s), 647/647, fail=0,与本地逐字一致);L0 假失败——gitlint 因 runner 无 git 身份而 exit 254(Missing git configuration: please set user.name),旧文案把它说成"提交信息违规",且该步 exit 1 连带让 26 个钩子全部没跑。已在 ci_gitlint_range.ps1 用 GIT_CONFIG_* 注入一次性身份(不写文件)并区分 254/1 退出码。另记:新建分支的首次 push 不触发 run,需 workflow_dispatch 或再推一个非文档提交。详见指南 §7 |
| 2026-10-12 | 🔀 本轮 CI 修复随 master 合入 v2-on-ui(该分支另有 21 个功能提交;冲突仅 AGENTS.md 与 docs/README.md 两处,解法是"保留其新版结构 + 把 CI 指针搬进对应位置")。因该分支门禁更多(26 钩子 / 10 单测套件 vs master 的 18 / 3),指南里写死的数字已改为规则 + 分分支快照,见指南 §6 / §7 / §10 |
| 2026-10-12 | ✅ 双看门狗缺陷实测收敛(管理员 -StartNow 清掉 3 个残留 → 单实例、链路恢复、runner online)。另修两处:daemon 日志走 stderr 被 PS 5.1 2>&1 包成 ErrorRecord(2 行真日志写成 8 行,每 4 行 3 行噪声)→ 启动器改 ForEach-Object { "$_" };-Status 诚实化(非管理员读不到 SYSTEM 进程命令行 → 明说需提权而非谎报"无看门狗";重启循环判据改看进程存活时长,不再靠不轮转日志的尾部字符串报假警)。详见指南 §7.3 |
| 2026-10-12 | 🔴 修复"双看门狗抢 .runner.lock"缺陷:Unregister-ScheduledTask 不停旧实例进程 → 孤儿看门狗养着旧 daemon 占锁,新看门狗每 10 秒失败一次,而 runner 网页照样 online、-Status 也说"在跑"。现 -StartNow 先清残留进程再启动、-Status 报重复实例与锁冲突。同日清理机器侧:config.yaml 头部错误指引("改用 sc.exe / New-Service")改为看门狗口径,删除已废弃的 deploy_runner_task.ps1 与 run_runner.cmd,check_env.ps1 提示同步改指 bootstrap |
| 2026-10-12 | 单一口径清理:合并稿初版对 4 处分歧"两说并存",现统一为本机实测现状——注册口径(gitea-runner v4.0.1 / D:\Docker\act_runner / 127.0.0.1:3001,旧 act_runner v0.2.11 + C:\act_runner 段删去可复制命令只留警示)、config.yaml(fetch_timeout: 1m0s、timeout: 30m0s)、常驻方式(只认看门狗,deploy_runner_task.ps1 标废弃)、验收数字(L0.5 288/288,历史数字标注为快照)。并补"机器侧遗留脚本勿误用"警示 |
| 2026-10-12 | 新建本目录:远程 CI 内容原先散在 docs/环境与部署/(两篇互相重叠的指南)、docs/测试说明/测试开发标准流程.md §9、AGENTS.md 提交门禁节共 4 处,约 2000 行;现合并为单一指南并把 AGENTS.md 压成一行指针。动因:远程 CI 只涉及本机一台 runner,与日常开发规范混在一起每次会话都被读,造成困惑 |