CI 文档单一口径清理:以本机实测现状为准,旧方案降级为"勿照抄"警示
合并稿初版对 4 处分歧采取"两说并存 + 衔接注",长期看是隐患(读者可能照抄失效方案)。 本次先实测取现状,再统一口径:gitea-runner v4.0.1 / D:\Docker\act_runner / --instance http://127.0.0.1:3001 / labels windows:host / config.yaml 实际值。 - 注册口径:删掉 act_runner v0.2.11 + C:\act_runner + 公网域名的可复制命令块,只留 "勿照抄"警示——核实 C:\act_runner 至今不存在,且 v0.2.x 与 v4 命令集不兼容, 照抄会装出连不上 Gitea 的 runner - config.yaml:示例 fetch_timeout 由 5m0s 改为磁盘实际值 1m0s(超 RPC timeout 1m 会被 截断并刷告警)、timeout 统一 30m0s,两处示例块对齐真实文件 - 常驻口径:§3.2 deploy_runner_task.ps1 标为已废弃并写清失效机理(单次 daemon 是 "正常退出",计划任务失败重启永不触发);§3.3 手动等价命令重写为看门狗版任务对象 (旧版会教人手搓出坏配置);§10 TL;DR 第 4 步改指 ci_runner_bootstrap.ps1 - 数字口径:L0.5 期望值更新为 288/288(2026-10-12 实测),run#8 的 39/39 与 278/278 标注为历史快照——判定只看 fail=0 与 A==B,不拿历史数字当基准 顺带同步到现状:健康三查与排障表改用现行日志名(runner-daemon.log / runner-watchdog.log;runner-stdout.log 标为遗留并说明其 ASCII+UTF-16LE 混编码); BOM 示例对象换成 check_env.ps1 并注明看门狗是纯 ASCII 无需 BOM;配套脚本表补 run_runner_watchdog.ps1,并警示磁盘上仍存的 deploy_runner_task.ps1 / run_runner.cmd 误执行会把看门狗任务覆盖回单次任务;补"Next Run Time 为空属开机触发器正常表现"。 保留不动:机器级 DTU_* 为正式通道、全局 site-packages 为兜底——这是设计的降级链, 不是文档分歧。 验证:check_doc_links.py --all 125 篇 0 问题;pre-commit run --all-files 17 项全 Passed。
This commit is contained in:
@@ -56,6 +56,11 @@
|
||||
> 变量;返回码 `0x41301` 是"任务正在运行"、`next run` 为空是开机触发器的正常表现,
|
||||
> 都不是故障(详见指南 §3.4)。
|
||||
|
||||
> 🗑 **机器侧遗留,别误用**:`D:\Docker\act_runner\` 下还留着旧方案的 `deploy_runner_task.ps1`
|
||||
> 与 `run_runner.cmd`。它们跑的是**单次** daemon——首次 Declare 失败就永久停摆(机理见指南
|
||||
> §3.2),而且**执行它会把看门狗任务覆盖回单次任务**。现行部署只有 `ci_runner_bootstrap.ps1`
|
||||
> 这一条路;那两个文件建议改名加 `.deprecated` 后缀或直接删除。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- 测试分层与门禁决策(L0~L3 各层由谁把关):[`../测试说明/测试开发标准流程.md`](../测试说明/测试开发标准流程.md)
|
||||
@@ -68,4 +73,5 @@
|
||||
|
||||
| 日期 | 变更 |
|
||||
|---|---|
|
||||
| 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,与日常开发规范混在一起每次会话都被读,造成困惑 |
|
||||
|
||||
+112
-104
@@ -212,26 +212,18 @@ CI 的两个 job 都是 `runs-on: windows`,所以**必须有一个 labels 含
|
||||
> 💡 **Token 存在于 `action_runner_token` 表**(MySQL,见本文 §6.1)。
|
||||
> 每仓库一个有效 token,**注册一次后即被消费**;过期(约 1 小时)或已用则需重新创建。
|
||||
|
||||
### 2.2 下载并注册 act_runner
|
||||
### 2.2 下载并注册 runner
|
||||
|
||||
> ⚠️ 下面这段是初版(act_runner v0.2.x 时代)的通用写法,按原样保留备查;
|
||||
> 本机实际部署请按 §2.2.1 起(**gitea-runner v4.0.1**,二进制名与目录都不同)。
|
||||
**本机现状(唯一口径)**:二进制 **`gitea-runner.exe` v4.0.1**(实测 20,623,872 B ≈ 20.6 MB),
|
||||
装在 **`D:\Docker\act_runner`**,注册 `--instance` 用 **`http://127.0.0.1:3001`**。
|
||||
具体步骤见 §2.2.1 起,命令集与字段语义见 §2.2.2 / §2.3。
|
||||
|
||||
```powershell
|
||||
# 1) 下载(示例版本,请取 releases 页最新 Windows amd64)
|
||||
# https://gitea.com/gitea/act_runner/releases
|
||||
Invoke-WebRequest -Uri "https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-windows-amd64.exe" `
|
||||
-OutFile "C:\act_runner\act_runner.exe"
|
||||
|
||||
# 2) 注册:URL 用 Gitea 根地址,token 用 2.1 复制的
|
||||
cd C:\act_runner
|
||||
.\act_runner.exe register `
|
||||
--no-interactive `
|
||||
--instance "https://gitea.bitnasdaq.vip" `
|
||||
--token "粘贴 Registration Token" `
|
||||
--name "win-stm32-ci" `
|
||||
--labels "windows:host"
|
||||
```
|
||||
> 🗑 **历史备查,勿照抄**:本文初版写的是 `act_runner` **v0.2.11** + `C:\act_runner` +
|
||||
> `--instance https://gitea.bitnasdaq.vip`。三点均已过时,且**本机从未这样部署过**
|
||||
> (2026-10-12 核实:`C:\act_runner` 至今不存在):
|
||||
> ① v0.2.x 与 v4 的**二进制名与命令集都不同**(v4 已无 `daemon install/start/stop/status`,见 §3.0);
|
||||
> ② 目录不同;③ `--instance` 填公网域名会多绕一圈 DNS + 反代,反代没配对内网 IP 就直接失败。
|
||||
> **照抄那段会装出一个连不上 Gitea 的 runner**,故原命令块已删除,只留此警示。
|
||||
|
||||
**关键点**:`--labels "windows:host"` 中的 `windows` 必须**逐字**与 workflow 的
|
||||
`runs-on: windows` 对应(Gitea runner 的 label 名是自定义的,默认是 `ubuntu-latest`,
|
||||
@@ -325,14 +317,15 @@ cd "D:\Docker\act_runner"
|
||||
|
||||
### 2.3 配置 `config.yaml`(可选但建议)
|
||||
|
||||
`C:\act_runner\config.yaml` 里确认/补充:
|
||||
`D:\Docker\act_runner\config.yaml` 里确认/补充(本机完整落地版见 §2.3.2):
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
labels:
|
||||
- "windows:host" # 与 register 一致
|
||||
capacity: 1 # 并行 job 数;单机建议 1,避免 cppcheck 抢 CPU
|
||||
timeout: 30m
|
||||
timeout: 30m0s
|
||||
fetch_timeout: 1m0s # 🔴 不得超过 RPC timeout(1m0s),否则被自动截断并告警
|
||||
cache:
|
||||
enabled: true
|
||||
```
|
||||
@@ -370,7 +363,7 @@ runner:
|
||||
file: .runner # 注册凭据(由 register 生成,勿手改)
|
||||
capacity: 1 # 并行 job 数;单机建议 1(cppcheck 吃 CPU)
|
||||
timeout: 30m0s # 单 job 超时;L0+L0.5 约 1~3 分钟
|
||||
fetch_timeout: 5m0s
|
||||
fetch_timeout: 1m0s # 🔴 不得超过 RPC timeout(1m0s):原写 5m0s 会被自动截断并刷告警,2026-10-02 已改
|
||||
fetch_interval: 2s
|
||||
# 🔴 标签:windows 必须与 workflow 的 runs-on: windows 逐字一致
|
||||
labels:
|
||||
@@ -473,10 +466,11 @@ powershell -ExecutionPolicy Bypass -File scripts\ci_runner_bootstrap.ps1 -Status
|
||||
|
||||
## 3. 常驻底层:为什么不能用 Windows 服务 + 任务计划程序手动方式
|
||||
|
||||
> 本节是 2026-10-02 的实测记录("不能用服务"的根因 + 任务计划程序手动方式),
|
||||
> 保留作根因依据与手动排障参考。**正式部署一律用 §2.4 的 `scripts/ci_runner_bootstrap.ps1`**——
|
||||
> 本节 §3.2 / §3.3 生成的 `run_runner.cmd` 跑的是**单次** daemon,2026-10-11 实测证明
|
||||
> 它首次 Declare 失败就退出、死了没人管(见 §2.4)。
|
||||
> 本节是 2026-10-02 的实测记录("不能用 Windows 服务"的根因)与任务对象字段说明,
|
||||
> 保留作根因依据与手动排障参考。**正式部署一律用 §2.4 的 `scripts/ci_runner_bootstrap.ps1`**:
|
||||
> §3.2 的旧脚本 `deploy_runner_task.ps1` 生成的是**单次** daemon,2026-10-11 实测证明它
|
||||
> 首次 Declare 失败就退出、死了没人管;§3.3 已改写为与现行 bootstrap **等价**的看门狗任务
|
||||
> 对象,只用于理解字段或在别的机器上手搓。
|
||||
|
||||
### 3.0 🔴 关键结论:**不能用 Windows 服务**
|
||||
|
||||
@@ -529,57 +523,62 @@ level=info msg="runner: win-stm32-ci, with version: v4.0.1, with labels: [window
|
||||
|
||||
**让这个窗口开着**,去 Gitea 页面确认 runner 是 Idle,然后 Ctrl+C 停掉、再做常驻。
|
||||
|
||||
### 3.2 一键部署脚本 `deploy_runner_task.ps1`(2026-10-02 方案,已被 §2.4 取代)
|
||||
### 3.2 🗑 已废弃:`deploy_runner_task.ps1`(2026-10-02 方案,被 §2.4 推翻)
|
||||
|
||||
管理员 PowerShell 执行:
|
||||
**不要再用它部署。** 它生成的 `run_runner.cmd` 跑的是**单次** `gitea-runner.exe daemon`
|
||||
(无循环、无重启语义),而 §2.4 已实测证明 daemon 首次 Declare 失败就**正常退出**——
|
||||
计划任务把它记成"成功结束",`-RestartCount` 永不触发,于是 Gitea 重启一次 CI 就永久停摆。
|
||||
|
||||
脚本流程(供辨认用):提权检查 → 前置文件检查 → 清理旧 Windows 服务 → 生成 `run_runner.cmd`
|
||||
→ `Register-ScheduledTask`(开机+登录双触发器、SYSTEM、最高权限、崩溃重启)→ 启动 → 校验存活。
|
||||
它的"崩溃重启"参数看着齐全,但**对"正常退出"完全无效**——这正是它失效的那一点。
|
||||
|
||||
> ⚠️ **这两个文件目前仍留在磁盘上**(`D:\Docker\act_runner\deploy_runner_task.ps1` 与
|
||||
> `run_runner.cmd`,2026-10-12 核实)。它们不在版本库里,属机器侧遗留;建议改名加
|
||||
> `.deprecated` 后缀或直接删除——**否则下次手滑执行,就会把看门狗任务覆盖回单次任务**,
|
||||
> 等于把 §2.4 的修复整个抹掉。现行部署一律用仓库里的 `scripts/ci_runner_bootstrap.ps1`。
|
||||
|
||||
### 3.3 手动等价命令(等价于 §2.4 的 bootstrap,用于理解任务对象)
|
||||
|
||||
日常请直接跑 `scripts/ci_runner_bootstrap.ps1 -SetEnv -StartNow`。下面是它注册的**等价**对象,
|
||||
只在需要理解字段或在别的机器上手搓时使用:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\deploy_runner_task.ps1"
|
||||
```
|
||||
$Dir = 'D:\Docker\act_runner'
|
||||
$launcher = Join-Path $Dir 'run_runner_watchdog.ps1' # 由 bootstrap 生成的看门狗
|
||||
|
||||
脚本流程:提权检查 → 前置文件检查(`gitea-runner.exe` / `config.yaml` / `.runner`)
|
||||
→ **清理旧的无效 Windows 服务**(若存在)→ 生成启动包装 `run_runner.cmd`
|
||||
→ `Register-ScheduledTask`(开机+登录双触发器、SYSTEM 账户、最高权限、崩溃重启)
|
||||
→ 启动任务 → 校验进程存活。
|
||||
# ① 动作:跑【看门狗】而不是 daemon 本体(单次 daemon 就是 §3.2 失效的根因)
|
||||
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
|
||||
-Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$launcher`"" `
|
||||
-WorkingDirectory $Dir
|
||||
|
||||
### 3.3 手动等价命令
|
||||
# ② 触发器:只要开机触发
|
||||
$trigger = New-ScheduledTaskTrigger -AtStartup
|
||||
$trigger.Delay = 'PT1M' # 给 Gitea 启动留时间(看门狗自己也会等,双保险)
|
||||
|
||||
不想用脚本时,管理员 PowerShell 逐条执行:
|
||||
# ③ 设置
|
||||
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
|
||||
-RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) `
|
||||
-ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew
|
||||
$settings.StartWhenAvailable = $true # 🔴 属【任务设置】,写在触发器上会抛异常
|
||||
|
||||
```powershell
|
||||
$Dir = "D:\Docker\act_runner"
|
||||
Register-ScheduledTask -TaskName 'GiteaActionsRunner' -Action $action -Trigger $trigger `
|
||||
-Settings $settings -User 'SYSTEM' -RunLevel Highest `
|
||||
-Description 'Gitea Actions Runner for STM32F4-Base CI (labels: windows:host)'
|
||||
|
||||
# ① 包装脚本(固定工作目录 + stdout 落盘)
|
||||
@"
|
||||
@echo off
|
||||
cd /d "$Dir"
|
||||
"$Dir\gitea-runner.exe" daemon --config "$Dir\config.yaml" >> "$Dir\log\runner-stdout.log" 2>&1
|
||||
"@ | Out-File "$Dir\run_runner.cmd" -Encoding ASCII
|
||||
|
||||
# ② 注册任务
|
||||
$action = New-ScheduledTaskAction -Execute "$Dir\run_runner.cmd" -WorkingDirectory $Dir
|
||||
$trgBoot = New-ScheduledTaskTrigger -AtStartup
|
||||
$trgBoot.Delay = 'PT30S'
|
||||
$trgLogon = New-ScheduledTaskTrigger -AtLogOn
|
||||
$prin = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
|
||||
$sets = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
|
||||
-StartWhenAvailable -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) `
|
||||
-ExecutionTimeLimit (New-TimeSpan -Seconds 0) -MultipleInstances IgnoreNew
|
||||
|
||||
Register-ScheduledTask -TaskName "GiteaActionsRunner" -Action $action `
|
||||
-Trigger @($trgBoot, $trgLogon) -Principal $prin -Settings $sets `
|
||||
-Description "Gitea Actions Runner for STM32F4-Base CI (labels: windows:host)"
|
||||
|
||||
# ③ 启动
|
||||
Start-ScheduledTask -TaskName "GiteaActionsRunner"
|
||||
# ④ 启动
|
||||
Start-ScheduledTask -TaskName 'GiteaActionsRunner'
|
||||
```
|
||||
|
||||
> ⚠️ **`ExecutionTimeLimit = 0`(不限时长)必须显式设置**——
|
||||
> 任务计划程序默认 72 小时强制结束任务,会让 runner 每 3 天被杀一次。
|
||||
|
||||
> ⚠️ **`-WorkingDirectory` 只对 `New-ScheduledTaskAction` 有效**(这是它区别于
|
||||
> WinPS 5.1 `New-Service` 的地方)。不过仍建议用 `.cmd` 包装再 `cd /d`,
|
||||
> 因为 SYSTEM 账户的默认工作目录不可控。
|
||||
> WinPS 5.1 `New-Service` 的地方)。SYSTEM 账户的默认工作目录不可控,所以启动器里
|
||||
> 仍要显式 `Set-Location` 或用绝对路径。
|
||||
|
||||
> 🗑 旧方案还额外挂了 `-AtLogOn` 触发器并以 `-LogonType ServiceAccount` 运行。现行口径
|
||||
> **只留开机触发**:runner 与登录会话无关,多一个触发器只会让人误以为"必须有人登录才行"。
|
||||
|
||||
### 3.4 任务管理速查
|
||||
|
||||
@@ -605,9 +604,12 @@ Unregister-ScheduledTask -TaskName GiteaActionsRunner -Confirm:$false # 完全
|
||||
> | `267014` (`0x41306`) | 任务被用户终止 |
|
||||
>
|
||||
> **判断 runner 是否健康,看这三项而不是 `LastTaskResult`**:
|
||||
> ① `Get-Process gitea-runner` 有进程;
|
||||
> ② `log\runner-stdout.log` 最新一行是 `declare successfully`;
|
||||
> ① `Get-Process gitea-runner` 有进程(其父进程应是跑 `run_runner_watchdog.ps1` 的 powershell);
|
||||
> ② `log\runner-daemon.log` 最新一行是 `declare successfully`;
|
||||
> ③ Gitea 页面 runner 显示 **Idle**(或 MySQL 查 `action_runner.last_online`)。
|
||||
>
|
||||
> ⚠️ **`Get-ScheduledTaskInfo` 的 `Next Run Time` 为空是正常的**——触发器是"开机 +1 分钟",
|
||||
> 没有下一个日历时间可报;常驻进程靠看门狗保活,不靠计划器反复拉起。别把空值当成"任务坏了"。
|
||||
|
||||
### 3.5 ⚠️ 清理遗留的无效服务
|
||||
|
||||
@@ -1003,7 +1005,7 @@ github.com 会在 checkout 步骤卡住/失败。三种处置:
|
||||
| 5 | `git push` 一次(或页面 Run workflow) | Actions 页出现运行中任务 |
|
||||
| 6 | `l0-gates` 日志 | `using python (…)` + `runner environment check passed`;`::notice::L0: pre-commit hooks -- passed=.. failed=0 skipped=..`;无 `.map` 时见 `::warning::` 体积门禁未跑 |
|
||||
| 7 | `l0-gates` 的 **提交信息门禁** 步骤 | `::notice::gitlint: N commit message(s) checked, 0 failed`(**这一行以前根本不存在**,见 §7) |
|
||||
| 8 | `l05-host-unit-tests` 日志 | `::notice::L0.5: 3 runner(s), 278/278 assertions passed, fail=0` |
|
||||
| 8 | `l05-host-unit-tests` 日志 | `::notice::L0.5: 3 runner(s), 288/288 assertions passed, fail=0`(**断言总数随单测增减而变**,2026-10-12 实测 288;判定只看 **`fail=0` 且 A==B**,不要拿历史数字当基准) |
|
||||
| 9 | job 运行页的 **Summary** 区块 | 出现 "L0 static gates" / "Commit message gate (gitlint)" / "L0.5 host-side unit tests" 小标题与汇总行 |
|
||||
| 10 | 提交记录旁出现 ✅ | CI 全绿 |
|
||||
|
||||
@@ -1071,7 +1073,7 @@ date +%s # 对比 last_online
|
||||
| `daemon install` 报 `accepts at most 0 arg(s)` | **v4 已移除该子命令,且无任何服务子命令** | **改用任务计划程序**(§3) |
|
||||
| 🔴 `Start-Service gitea-runner` 报 **无法启动服务**(错误 1053) | **`daemon` 不是服务型程序**,不向 SCM 回报 `SERVICE_RUNNING` | **删除该服务,改用任务计划程序**(§3.0 / §3.5) |
|
||||
| `Register-ScheduledTask` 报 **拒绝访问** | Shell 未提权(`IsAdmin=False`) | 右键 PowerShell → **以管理员身份运行**(§3.6) |
|
||||
| 任务 `LastTaskResult` 非 0 | 启动包装脚本路径/权限问题 | 看 `log\runner-stdout.log`;确认 `.cmd` 存在且为 ASCII 编码 |
|
||||
| 任务 `LastTaskResult` 非 0 | 启动器路径/权限问题,或任务被手工终止 | 看 `log\runner-watchdog.log` 与 `log\runner-daemon.log`;确认 `run_runner_watchdog.ps1` 存在且为纯 ASCII;`0x41301` 是"正在运行"不是错误 |
|
||||
| `l0-gates` 报 `Cannot find: pwsh in PATH` | `shell: pwsh` = PS7,本机只有 WinPS 5.1 | 改 `shell: powershell` |
|
||||
| 🔴 `doc-links` 钩子本地过、CI 挂 | 引用了 **gitignore 的运行时文件**(如 `.dsh/skills/serial-assistant/scripts/state/*.json`),本地存在、干净克隆里没有 | 该行加状态词「未创建/不存在」等(§4.1.2) |
|
||||
| 任务跑满 72 小时被杀 | 计划任务默认 `ExecutionTimeLimit` | 设为 `0`(不限时长),见 §3.3 警示 |
|
||||
@@ -1093,14 +1095,14 @@ date +%s # 对比 last_online
|
||||
|
||||
```powershell
|
||||
# 方法 A:PowerShell 重存为 UTF8BOM
|
||||
$c = Get-Content "D:\Docker\act_runner\deploy_runner_task.ps1" -Raw -Encoding UTF8
|
||||
[System.IO.File]::WriteAllText("D:\Docker\act_runner\deploy_runner_task.ps1", $c, (New-Object System.Text.UTF8Encoding($true)))
|
||||
$c = Get-Content "D:\Docker\act_runner\check_env.ps1" -Raw -Encoding UTF8
|
||||
[System.IO.File]::WriteAllText("D:\Docker\act_runner\check_env.ps1", $c, (New-Object System.Text.UTF8Encoding($true)))
|
||||
```
|
||||
|
||||
```bash
|
||||
# 方法 B:直接前缀 BOM 字节(bash/Git Bash)
|
||||
cd "/d/Docker/act_runner"
|
||||
for f in deploy_runner_task.ps1 check_env.ps1; do
|
||||
for f in check_env.ps1; do
|
||||
printf '\xef\xbb\xbf' > "$f.tmp" && cat "$f" >> "$f.tmp" && mv "$f.tmp" "$f"
|
||||
done
|
||||
```
|
||||
@@ -1108,7 +1110,7 @@ done
|
||||
**校验**:用 PowerShell 解析器(不执行)确认语法干净:
|
||||
|
||||
```powershell
|
||||
foreach ($f in @("deploy_runner_task.ps1","check_env.ps1")) {
|
||||
foreach ($f in @("check_env.ps1","run_runner_watchdog.ps1")) {
|
||||
$errs = $null
|
||||
$null = [System.Management.Automation.Language.Parser]::ParseFile(
|
||||
"D:\Docker\act_runner\$f", [ref]$null, [ref]$errs)
|
||||
@@ -1119,7 +1121,11 @@ foreach ($f in @("deploy_runner_task.ps1","check_env.ps1")) {
|
||||
> 💡 替代方案:改用 **PowerShell 7+(`pwsh`)**,它默认按 UTF-8 读脚本、无需 BOM。
|
||||
> 但本机只有 WinPS 5.1,故加 BOM 最省事。
|
||||
>
|
||||
> 💡 **纯 ASCII 的脚本不受影响**。本目录的 `.ps1` 均含中文注释,现已统一加 BOM。
|
||||
> 💡 **纯 ASCII 的脚本不受影响,也不需要 BOM**。现行两个文件的口径:
|
||||
> `check_env.ps1` 含中文注释 → **必须带 BOM**;`run_runner_watchdog.ps1`(由
|
||||
> `scripts/ci_runner_bootstrap.ps1` 生成)**刻意写成纯 ASCII**,因此对编码免疫——
|
||||
> 生成它的模板也要求纯 ASCII,理由见仓库 `AGENTS.md` 的编码铁律。
|
||||
> 🗑 旧脚本 `deploy_runner_task.ps1` 已废弃(§3.2),不再作为示例对象。
|
||||
|
||||
### 7.2 日志位置与查看方式
|
||||
|
||||
@@ -1127,8 +1133,10 @@ foreach ($f in @("deploy_runner_task.ps1","check_env.ps1")) {
|
||||
|
||||
| 日志 | 位置 |
|
||||
|---|---|
|
||||
| runner **自身** stdout/stderr | `D:\Docker\act_runner\log\runner-stdout.log`(由 `run_runner.cmd` 重定向) |
|
||||
| runner **自身** stdout/stderr | `D:\Docker\act_runner\log\runner-daemon.log`(由看门狗 `Out-File -Append -Encoding utf8` 落盘) |
|
||||
| **看门狗自身**动作(等 Gitea / 拉起 / 退出码 / 重拉) | `D:\Docker\act_runner\log\runner-watchdog.log`(ASCII) |
|
||||
| **每个 job** 的详细日志 | `D:\Docker\act_runner\log\job\` |
|
||||
| 🗑 历史遗留 | `log\runner-stdout.log` 是旧 `run_runner.cmd` 时代的文件,**已不再写入**;它内部混着 ASCII 与 UTF-16LE 两种编码(PS 5.1 `*>>` 默认 UTF-16LE),按 UTF-8 读会看到"每个字节后跟一个 NUL"的 `t i m e = ...` 形态,属正常现象不是新故障 |
|
||||
|
||||
**看日志**:v4 的 `log` 段**没有 `file` 键**,两种落盘方式:
|
||||
|
||||
@@ -1247,32 +1255,26 @@ Invoke-WebRequest -Uri "https://gitea.com/gitea/runner/releases/download/v4.0.1/
|
||||
# 3) 前台试跑,确认能连上
|
||||
.\gitea-runner.exe daemon # 看到 "labels: [windows] ... declare successfully" 即成功,Ctrl+C 停
|
||||
|
||||
# 4) 常驻 —— ⚠️ daemon 不是服务型程序,必须用【任务计划程序】(管理员 PowerShell)
|
||||
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\deploy_runner_task.ps1"
|
||||
# 4) 常驻 —— ⚠️ daemon 不是服务型程序,且首次 Declare 失败就直接退出进程
|
||||
# 所以必须【看门狗循环 + 开机计划任务】,一条命令搞定(管理员 PowerShell,在仓库根目录):
|
||||
powershell -ExecutionPolicy Bypass -File scripts\ci_runner_bootstrap.ps1 -SetEnv -StartNow
|
||||
|
||||
# 等价手动:
|
||||
# Register-ScheduledTask -TaskName GiteaActionsRunner -Action (
|
||||
# New-ScheduledTaskAction -Execute "D:\Docker\act_runner\run_runner.cmd") `
|
||||
# -Trigger (New-ScheduledTaskTrigger -AtStartup) `
|
||||
# -Principal (New-ScheduledTaskPrincipal -UserId SYSTEM -LogonType ServiceAccount -RunLevel Highest)
|
||||
# Start-ScheduledTask -TaskName GiteaActionsRunner
|
||||
# 体检(四项:计划任务 / daemon 进程 / Gitea 可达 / 机器级 DTU_*)—— 须管理员:
|
||||
powershell -ExecutionPolicy Bypass -File scripts\ci_runner_bootstrap.ps1 -Status
|
||||
# 干跑(只打印将要写入的启动器与任务对象,不落盘不注册)—— 免管理员:
|
||||
powershell -ExecutionPolicy Bypass -File scripts\ci_runner_bootstrap.ps1 -DryRun
|
||||
|
||||
# 5) ⚠️⚠️ 把 pre-commit 装到【全局】site-packages(否则 L0 必挂,见 §4.1.1)
|
||||
# —— 这是本环境最容易漏、也最难自己看出来的一步(用户态对 SYSTEM 不可见)
|
||||
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\install_precommit_global.ps1"
|
||||
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\install_precommit_global2.ps1"
|
||||
# 若有包报"安装成功"但 import 失败(pip 静默跳过):
|
||||
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\fix_cfgv_global.ps1"
|
||||
|
||||
# 5b) 2026-10-02 起推荐:改设机器级 DTU_* 变量(§4.1.3,显式覆盖、报错直指变量名);
|
||||
# 全局 site-packages 安装保留为未设变量时的兜底。设完同样要重启 runner 任务。
|
||||
# (管理员 PowerShell;值按本机实际路径改)
|
||||
# [Environment]::SetEnvironmentVariable('DTU_PRECOMMIT_PYTHON', 'C:\ProgramData\anaconda3\python.exe', 'Machine')
|
||||
# 5) 工具链必须对 SYSTEM 可见(runner 以 SYSTEM 跑,看不见交互用户的 PATH 与用户级 site)
|
||||
# 正式通道 = 机器级 DTU_* 变量,上一步的 -SetEnv 已自动发现并写入;需手工覆盖时:
|
||||
# (管理员 PowerShell;下面是本机实测现值,换机按实际路径改)
|
||||
# [Environment]::SetEnvironmentVariable('DTU_PRECOMMIT_PYTHON', 'C:\ProgramData\Anaconda3\python.exe', 'Machine')
|
||||
# [Environment]::SetEnvironmentVariable('DTU_CPPCHECK', 'C:\Program Files\Cppcheck\cppcheck.exe', 'Machine')
|
||||
# [Environment]::SetEnvironmentVariable('DTU_MSVC_CL', '<本机 x64 cl.exe 完整路径>', 'Machine')
|
||||
# 兜底通道(只有变量没设时才会走到):把 pre-commit 装进【全局】site-packages,见 §4.1.1
|
||||
# ⚠️ 改过任何环境变量都必须 Stop 再 Start 任务——环境块是任务启动时的快照
|
||||
|
||||
# 6) 复验(-s = 模拟 SYSTEM 视角,必须过)
|
||||
& 'C:\ProgramData\anaconda3\python.exe' -s -m pre_commit --version # pre-commit 4.6.2
|
||||
& 'C:\ProgramData\Anaconda3\python.exe' -s -m pre_commit --version # pre-commit 4.6.2
|
||||
|
||||
# 7) 回网页确认 runner 为 Idle → 触发 CI
|
||||
# push 触发(注意:纯 .md 改动在 workflow 的 paths-ignore 里,不会触发);
|
||||
@@ -1282,22 +1284,27 @@ powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\fix_cfgv_global.p
|
||||
# "https://gitea.bitnasdaq.vip/api/v1/repos/wandering1/STM32F4-Base/actions/workflows/ci.yml/dispatches"
|
||||
```
|
||||
|
||||
> ⚠️ 上面第 4 步是 2026-10-02 的方案(计划任务跑**单次** daemon)。2026-10-11 实测证明
|
||||
> 单次 daemon 首次 Declare 失败即退出、计划任务的失败重启救不到它——
|
||||
> **正式部署一律用 §2.4 的 `scripts/ci_runner_bootstrap.ps1`**(看门狗循环重拉 + 开机计划任务)。
|
||||
> 🗑 本清单第 4 步在 2026-10-02 版里是"计划任务跑**单次** daemon"(`deploy_runner_task.ps1`)。
|
||||
> 2026-10-11 实测证明单次 daemon 首次 Declare 失败即退出、计划任务的失败重启救不到它,
|
||||
> 故已改写为看门狗方案;旧脚本的失效机理见 §3.2。
|
||||
|
||||
> **CI 验收标准**(2026-10-02 已达成,run#8):`action_run_job` 里两个 job 均 `status=1`——
|
||||
> `l0-gates`(14 个 pre-commit 钩子全 Passed,`内存/Flash` 在无 `.map` 时 Skipped)
|
||||
> + `l05-host-unit-tests`(MSVC 探测 + 39/39 单测)。
|
||||
> **CI 验收标准**:两个 job 都要 `status=1`。**现行口径**(2026-10-12):`l0-gates` 报
|
||||
> **17 条钩子**(`passed=16 skipped=1`,配置里定义 18 个,gitlint 属 `commit-msg` stage 故不在
|
||||
> `--all-files` 报告内,见 §7)+ 提交信息门禁 `::notice::gitlint: N checked, 0 failed`;
|
||||
> `l05-host-unit-tests` 报 `3 runner(s), 288/288 assertions passed, fail=0`。
|
||||
> 🗑 历史快照(勿当基准):run#8(2026-10-02)当时是"14 个钩子全 Passed + 39/39 单测"——
|
||||
> 钩子数与断言数都随仓库演进而变,**判定只看 `fail=0`、`failed=0` 与 A==B**。
|
||||
|
||||
**配套脚本**(均在 `D:\Docker\act_runner\`,**均已加 UTF-8 BOM**,可直接在 WinPS 5.1 运行):
|
||||
**配套脚本**:
|
||||
|
||||
| 脚本 | 用途 | 需要管理员 |
|
||||
|---|---|---|
|
||||
| `check_env.ps1` | 环境自检(Gitea 可达 / 工具链 / MSVC / 任务状态) | 否 |
|
||||
| `deploy_runner_task.ps1` | **一键部署**(自检 + 清旧服务 + 建计划任务 + 启动 + 验证) | **是** |
|
||||
| 脚本 | 位置 | 用途 | 需要管理员 |
|
||||
|---|---|---|---|
|
||||
| `ci_runner_bootstrap.ps1` | **仓库 `scripts/`** | **现行唯一部署/体检入口**(`-Status` / `-DryRun` / `-SetEnv -StartNow`) | `-Status`、`-SetEnv -StartNow` 需要 |
|
||||
| `check_env.ps1` | `D:\Docker\act_runner\` | 环境自检(Gitea 可达 / 工具链 / MSVC / 任务状态) | 否 |
|
||||
| `run_runner_watchdog.ps1` | `D:\Docker\act_runner\` | **看门狗启动器**,由 bootstrap 生成,是计划任务的动作目标。**纯 ASCII,不需要 BOM** | 由任务以 SYSTEM 跑 |
|
||||
| 🗑 `deploy_runner_task.ps1`、`run_runner.cmd` | `D:\Docker\act_runner\` | **已废弃**(单次 daemon,§3.2)。仍在磁盘上,建议改名加 `.deprecated` 或删除,免得误执行把看门狗任务覆盖回单次任务 | — |
|
||||
|
||||
> 早前基于 Windows 服务的 `deploy_runner.ps1` / `install_service.ps1` 已删除
|
||||
> 更早基于 Windows 服务的 `deploy_runner.ps1` / `install_service.ps1` 已删除
|
||||
> —— 那条路走不通(§3.0)。
|
||||
|
||||
---
|
||||
@@ -1306,6 +1313,7 @@ powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\fix_cfgv_global.p
|
||||
|
||||
| 日期 | 变更 |
|
||||
|---|---|
|
||||
| 2026-10-12 | 🧹 **单一口径清理(以本机实测现状为准)**:合并稿初版对 4 处分歧采取"两说并存 + 衔接注",本次统一。① 注册口径——`act_runner v0.2.11` + `C:\act_runner` + 公网域名 instance 一段**删除可复制命令**,只留"勿照抄"警示(核实 `C:\act_runner` 至今不存在,本机是 `gitea-runner v4.0.1` + `D:\Docker\act_runner` + `127.0.0.1:3001`);② `config.yaml` 示例 `fetch_timeout` 由 `5m0s` 改为磁盘实际值 **`1m0s`**、`timeout` 统一 `30m0s`,并补"不得超过 RPC timeout(1m0s)";③ 常驻口径统一为看门狗——§3.2 `deploy_runner_task.ps1` 标为**已废弃**并说明失效机理(单次 daemon = 正常退出,失败重启永不触发),§3.3 手动等价命令**重写为看门狗版任务对象**(旧版会教人手搓出坏配置),§10 TL;DR 第 4 步改指 `ci_runner_bootstrap.ps1`;④ 数字口径——L0.5 期望值更新为 **288/288**(run#8 的 39/39 与 278/278 标注为历史快照,判定只看 `fail=0` 与 A==B),钩子数按现行 18 定义 / 17 报告。另同步:健康三查与排障表改用现行日志名(`runner-daemon.log` / `runner-watchdog.log`,`runner-stdout.log` 标为遗留且说明其混编码)、BOM 示例对象换成 `check_env.ps1` 并注明看门狗是纯 ASCII 无需 BOM、配套脚本表补 `run_runner_watchdog.ps1` 并标出磁盘上仍存的废弃脚本建议删除、补 `Next Run Time` 为空属正常的说明 |
|
||||
| 2026-10-12 | **文档合并**:本次把 `CI配置指南.md` 与 `Gitea_Runner部署指南.md` 合并为本篇(`docs/CI/远程CI完整指南.md`)并迁入 `docs/CI/`,去重(runner 注册 / config.yaml / 装软件 / 排障表两篇均有)、补入 runner 看门狗与机器级变量实测教训;相对链接按新位置改写,原两篇互引改为本文内部引用 |
|
||||
| 2026-10-11 | **bootstrap 自身修复**:`StartWhenAvailable` 误设到**触发器**上(该属性属**任务设置**,触发器没有)→ 脚本在"已注销旧任务、尚未注册新任务"之间抛 `SetValueInvocationException`,把 runner 任务删没了。现改为①先构建 action/trigger/settings、**后**注销旧任务,②`Register-ScheduledTask` 失败时显式告警"旧任务已删、CI 裸奔",③新增 **`-DryRun`**(免管理员即可全量校验任务对象),④`-Status` 在非管理员下额外提示"看不见任务 ≠ 任务不存在"。同时更正根因:旧任务其实存在,但跑的是**单次** `daemon`——daemon 属"正常退出"而非"失败",计划任务的失败重启**救不到**它,必须用看门狗循环重拉 |
|
||||
| 2026-10-11 | **修"很多任务不执行"(runner 静默停摆)+ 补 gitlint 门禁**:① §2.4 重写——`gitea-runner` v4 的 `daemon` **无服务支持、首次 Declare 失败即退出进程**(日志实证),Gitea/机器重启一次 CI 就停摆,**run 16~21 共 12 个 job 零日志**(`cancelled`/`queued`,叠加 `cancel-in-progress` 后表现为"任务凭空消失"而非失败);新增 **`scripts/ci_runner_bootstrap.ps1`**(等 Gitea 就绪 + 崩溃自拉起的看门狗 + 开机计划任务 + `-SetEnv` 写机器级 `DTU_*` + `-Status` 只读体检)。② §3.1 重写——SYSTEM 可见性三重坑(PATH python 是 msys64 无 pre-commit / 用户级 site 对 SYSTEM 不可见 / `.venv` 已 gitignore)是 run 14~15 L0 全灭根因(`33a4aa4` 把候选收窄成这两个、又删了 cppcheck 目录兜底,而机器级 `DTU_*` 从未设置);探测收进 **`scripts/ci_find_python.ps1`**(两 job 共用、可离线自测、失败列出全部候选)并恢复机器级安装兜底。③ 新增 **gitlint 提交信息门禁**:钩子定义数比 CI 报告条数多 **1**(当时 17/16,master 并入 `test-cppcheck` 后为 18/17),缺的正是 gitlint——其 `stages: [commit-msg]` 声明在**上游** `.pre-commit-hooks.yaml`(`--all-files` 跑不到,且表现为全绿 → 长期无人发现)→ **`scripts/ci_gitlint_range.ps1`** 逐条校验本次 push/PR 范围(消息文件须写在仓库内 + UTF-8 无 BOM)。④ `GITHUB_ENV/PATH/OUTPUT` 写入统一显式 `-Encoding ascii`(PS 5.1 `Out-File -Append` 默认 **UTF-16LE**,实测落盘 `42 00 42 00 42 00 3D 00 31 00`)。§5 清单 8→10 条、§6 排障表 +5 行、§7 维护项重写 |
|
||||
|
||||
Reference in New Issue
Block a user