文档:修正 Runner 常驻方案为任务计划程序

实测确认 gitea-runner v4.0.1 的 daemon 是纯控制台程序,不含任何
Windows 服务管理代码(命令集仅 bug-report/cache-server/config/
daemon/exec/register,无 service.go),用 sc.exe 注册服务后
Start-Service 必然报错 1053。二进制内出现的 OpenSCManagerW/
CreateServiceW 等符号来自 Docker SDK,与服务安装无关。

- Gitea_Runner部署指南 §4 全节重写为任务计划程序方案:新增 §4.0
  根因分析、§4.2 一键脚本 deploy_runner_task.ps1、§4.3 手动命令
  (含 72h ExecutionTimeLimit 警示)、§4.5 清理遗留服务、§4.6 提权
- 排障表补错误 1053 / LastTaskResult 非 0 / 72 小时被杀 3 条
- 拓扑图、§5.1 PATH 运行账户、§7 日志位置、§10 TL;DR 同步更新
This commit is contained in:
2026-10-02 01:01:11 +08:00
parent 018ee9527e
commit 164fd3ec23
+165 -88
View File
@@ -14,11 +14,15 @@
> ⚠️ **重要版本变更(2026-10-02 实测)**:act_runner 已更名为 **`gitea-runner`**,
> 当前最新版 **v4.0.1**(发布页 `https://gitea.com/gitea/runner/releases`,
> 注意仓库路径已从 `gitea/act_runner` 变为 **`gitea/runner`**)。
> **v4 移除了 `daemon install/start/stop/status` 子命令**(那些是 v0.2.x 的接口),
> 常驻改用 **Windows 原生 `sc.exe` / `New-Service`** —— 见 §4。
> **v4 移除了 `daemon install/start/stop/status` 子命令**(那些是 v0.2.x 的接口)。
> 另:v4 的 `log` 段只有 `level` 和 `job`(**无 `file` 键**),配置用
> `gitea-runner config init / set / get / generate` 管理。
> 🔴 **常驻方式修正(2026-10-02 实测推翻)**:`gitea-runner daemon` 是**纯控制台程序**,
> **不支持作为 Windows 服务运行**(二进制内无服务管理代码,也无 `service.go`);
> 用 `sc.exe` / `New-Service` 注册后 `Start-Service` 必然失败。
> **正确方式是 Windows 任务计划程序** —— 见 **§4**。
---
## 0. 先理解:这台机器上的拓扑
@@ -33,7 +37,7 @@
│ │ ① runner 注册 / 心跳 / 领任务:走 http://127.0.0.1:3001 │
│ │ (本地回环,不经公网、不依赖 DNS/反代) │
│ │ │
│ gitea-runner.exe ── Windows 服务(win-stm32-ci) │
│ gitea-runner.exe ── 计划任务 GiteaActionsRunner(win-stm32-ci) │
│ │ │
│ └─ ② 领到 job 后,直接在**本机**跑: │
│ git fetch / pre-commit / cppcheck / cl.exe │
@@ -224,15 +228,48 @@ container:
---
## 4. 让 Runner 常驻(Windows 服务)
## 4. 让 Runner 常驻(任务计划程序)
### 4.0 🔴 关键结论:**不能用 Windows 服务**
> **本条为 2026-10-02 实测推翻既有假设后的修正结论,务必先读。**
先前本文档(及 `install_service.ps1`)主张用 `sc.exe` / `New-Service` 把
`gitea-runner daemon` 注册成 Windows 服务。**实测不可行**,`Start-Service` 必然失败:
```
Start-Service : 由于以下错误无法启动服务"Gitea Actions Runner (gitea-runner)" ...
```
**根因(对 `gitea-runner.exe` v4.0.1 二进制逆向确认)**:
| 证据 | 结论 |
|---|---|
| 命令集只有 `bug-report` / `cache-server` / `config` / `daemon` / `exec` / `register`(对应源码 `internal/app/cmd/{bug_report,cache-server,cmd,config,daemon,exec,register}.go`) | **没有 `service.go`,没有任何服务管理子命令** |
| `daemon --help` 仅 `--labels` / `--once` 两个 flag | daemon 无服务模式开关 |
| 二进制内虽出现 `OpenSCManagerW` / `CreateServiceW` / `StartServiceCtrlDispatcherW` 等符号 | 它们来自 **Docker SDK**(容器作业路径),**不是** runner 的服务安装代码——切勿据此误判 |
**`daemon` 是纯控制台程序**:它从不调用 `StartServiceCtrlDispatcher`,
因此 SCM 启动它后收不到 `SERVICE_RUNNING` 回报,判定超时 → 报错 1053。
**正确做法:Windows 任务计划程序(Task Scheduler)。**
它是控制台程序常驻的标准手段,功能上等价于服务:
| 服务能做的 | 任务计划程序对应能力 |
|---|---|
| 开机自启 | 触发器 `-AtStartup`(+ 延迟 30s 让 Gitea 先起) |
| 不登录也运行 | 以 `SYSTEM` 账户运行 |
| 最高权限 | `-RunLevel Highest` |
| 崩溃自动重启 | `-RestartCount 999 -RestartInterval 1min` |
| 开机/手动启停 | `Enable/Disable/Start/Stop-ScheduledTask` |
### 4.1 前台先试跑(强烈建议)
**先别急着装服务**——用前台模式确认能连上:
**先别急着常驻**——用前台模式确认能连上:
```powershell
cd "D:\Docker\act_runner"
.\gitea-runner.exe daemon
.\gitea-runner.exe daemon --config .\config.yaml
```
看到这两行即成功:
@@ -242,88 +279,102 @@ level=info msg="Starting runner daemon"
level=info msg="runner: win-stm32-ci, with version: v4.0.1, with labels: [windows], declare successfully"
```
**让这个窗口开着**,去 Gitea 页面确认 runner 是 Idle,然后再 Ctrl+C 停掉、装服务。
**让这个窗口开着**,去 Gitea 页面确认 runner 是 Idle,然后 Ctrl+C 停掉、再做常驻。
### 4.2 ⚠️ v4 没有 `daemon install` —— 用 `sc.exe` 注册服务
### 4.2 一键部署脚本(推荐)
**这是与旧版文档最大的差异。** v4.0.1 的 `daemon` 只接受 `--labels` / `--once` 两个 flag,
`daemon install` 会报 `Error: accepts at most 0 arg(s)`。
**正确做法**——在**管理员** PowerShell 中执行(脚本已备好:
`D:\Docker\act_runner\install_service.ps1`):
管理员 PowerShell 执行:
```powershell
# ① 创建服务(路径含空格必须加引号;--config 用绝对路径)
sc.exe create gitea-runner `
binPath= '"D:\Docker\act_runner\gitea-runner.exe" daemon --config "D:\Docker\act_runner\config.yaml"' `
start= auto `
DisplayName= "Gitea Actions Runner"
# ② 描述
sc.exe description gitea-runner "Gitea Actions Runner for STM32F4-Base CI (windows:host)"
# ③ 失败自动重启(5 秒后重试,最多 3 次;86400 秒后重置计数)
sc.exe failure gitea-runner reset= 86400 actions= restart/5000/restart/5000/restart/5000
# ④ 启动
sc.exe start gitea-runner
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\deploy_runner_task.ps1"
```
> ⚠️ `sc.exe` 的 `key= value` 语法:**等号后必须有空格,等号前不能有空格**,否则报参数错误。
> 这是 `sc` 的历史怪癖,不是笔误。
脚本流程:提权检查 → 前置文件检查(`gitea-runner.exe` / `config.yaml` / `.runner`)
→ **清理旧的无效 Windows 服务**(若存在)→ 生成启动包装 `run_runner.cmd`
→ `Register-ScheduledTask`(开机+登录双触发器、SYSTEM 账户、最高权限、崩溃重启)
→ 启动任务 → 校验进程存活。
**或用 PowerShell 原生 `New-Service`**(注意 Windows PowerShell 5.1 **没有 `-WorkingDirectory` 参数**,
所以要靠 `--config` 绝对路径兜住工作目录):
### 4.3 手动等价命令
不想用脚本时,管理员 PowerShell 逐条执行:
```powershell
New-Service -Name "gitea-runner" `
-BinaryPathName '"D:\Docker\act_runner\gitea-runner.exe" daemon --config "D:\Docker\act_runner\config.yaml"' `
-DisplayName "Gitea Actions Runner" `
-Description "Gitea Actions Runner for STM32F4-Base CI" `
-StartupType Automatic
Start-Service -Name "gitea-runner"
$Dir = "D:\Docker\act_runner"
# ① 包装脚本(固定工作目录 + 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"
```
**期望**:`Get-Service gitea-runner` → `Status: Running`。
> ⚠️ **`ExecutionTimeLimit = 0`(不限时长)必须显式设置**——
> 任务计划程序默认 72 小时强制结束任务,会让 runner 每 3 天被杀一次。
### 4.3 一键脚本(推荐)
> ⚠️ **`-WorkingDirectory` 只对 `New-ScheduledTaskAction` 有效**(这是它区别于
> WinPS 5.1 `New-Service` 的地方)。不过仍建议用 `.cmd` 包装再 `cd /d`,
> 因为 SYSTEM 账户的默认工作目录不可控。
仓库内已提供两个脚本(**都需管理员 PowerShell**):
| 脚本 | 用途 |
|---|---|
| `D:\Docker\act_runner\deploy_runner.ps1` | **一键全流程**:环境自检 → 检查注册 → 装服务 → 启动 → 验证 |
| `D:\Docker\act_runner\install_service.ps1` | 只做「装服务」(注册已完成时用) |
| `D:\Docker\act_runner\check_env.ps1` | 只做「环境自检」(Gitea 可达 / 工具链 / MSVC / 服务状态) |
### 4.4 任务管理速查
```powershell
# 管理员 PowerShell
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\deploy_runner.ps1"
Get-ScheduledTask -TaskName GiteaActionsRunner # 状态
Get-ScheduledTaskInfo -TaskName GiteaActionsRunner # 上次运行结果
Start-ScheduledTask -TaskName GiteaActionsRunner # 启动
Stop-ScheduledTask -TaskName GiteaActionsRunner # 停止
Disable-ScheduledTask -TaskName GiteaActionsRunner # 禁用自启
Enable-ScheduledTask -TaskName GiteaActionsRunner # 恢复自启
Unregister-ScheduledTask -TaskName GiteaActionsRunner -Confirm:$false # 完全卸载
```
### 4.4 服务管理速查
改完 `config.yaml` 后需 **Stop 再 Start** 任务才生效。
### 4.5 ⚠️ 清理遗留的无效服务
若早前按旧文档建过服务,删掉它(留着只会误导):
```powershell
Get-Service gitea-runner # 状态
Stop-Service gitea-runner # 停止
Start-Service gitea-runner # 启动
Restart-Service gitea-runner # 重启(改完 config.yaml 后必须)
sc.exe delete gitea-runner # 删除服务(卸载)
Stop-Service gitea-runner -Force -ErrorAction SilentlyContinue
sc.exe delete gitea-runner
```
### 4.5 ⚠️ 权限要求(本机实测的硬约束)
> **`gitea-runner` 这个名字将不再作为服务存在。** 之后提到"gitea-runner"
> 一律指**计划任务 `GiteaActionsRunner`** 或**进程 `gitea-runner.exe`**。
**安装 Windows 服务必须用「提权的管理员」Shell**。本机实测:
### 4.6 ⚠️ 权限要求(本机实测的硬约束)
**注册计划任务必须用「提权的管理员」Shell**。本机实测:
| 检查项 | 结果 |
|---|---|
| 当前用户 | `DESKTOP-KM0OG7Q\Administrator` |
| 是否提权(`IsInRole(Administrator)`) | **False** |
| 尝试 `New-Service` | ❌ `拒绝访问`(CreateService 需要 elevated token) |
| 非提权下注册任务 | ❌ `拒绝访问`(`Register-ScheduledTask` 需要 elevated token) |
> **"是 Administrator 用户" ≠ "有管理员权限"** —— Windows 的 UAC 会把普通登录会话降权。
> 必须**右键 PowerShell → 以管理员身份运行**,标题栏会显示「管理员」字样。
> 💡 计划任务以 **`SYSTEM`** 账户运行,拥有完整权限,可正常访问本地
> `127.0.0.1:3001` 的 Gitea。
---
## 5. Runner 必须装齐的软件
@@ -350,17 +401,23 @@ MSVC : VS2019 BuildTools 14.29.30133 (Hostx64\x64\cl.exe) ✅
**→ 四项全齐,无需额外安装。**
### 5.1 ⚠️ 关键坑:PATH 与服务账号
### 5.1 ⚠️ 关键坑:PATH 与运行账户
**问题的本质**:`act_runner` 作为 Windows 服务运行时,继承的是**安装服务那个时刻的系统 PATH**。
**问题的本质**:计划任务以 **`SYSTEM`** 账户运行时,继承的是**系统级 PATH**
(注册表 `HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment` 的 `Path`),
**不含任何用户级 PATH**。
- 你在某个终端里能用 `python`,**不代表 runner 服务里也能用**;
- **装完任何新软件 / 改过 PATH 后,必须重启 runner 服务**:
- 你在自己的终端里能用 `python`,**不代表 SYSTEM 账户里也能用**;
- **装完任何新软件 / 改过系统 PATH 后,必须重启 runner 任务**:
```powershell
Restart-Service gitea-runner
Stop-ScheduledTask -TaskName GiteaActionsRunner
Start-ScheduledTask -TaskName GiteaActionsRunner
```
> **核对方法**:用 `check_env.ps1` 的「系统 PATH 视角」检查项,
> 或以 SYSTEM 身份跑一次 `where python` 验证。
### 5.2 ⚠️ 关键坑:MSVC 的路径必须"标准"
CI 的 MSVC 探测(`l05` job)会去这几个**固定根目录**找
@@ -438,21 +495,23 @@ date +%s # 对比 last_online
| 现象 | 根因 | 处置 |
|---|---|---|
| runner 一直 **Idle**,push 后任务**排队不跑** | `--labels` 不是 `windows`(最常见) | 改 `config.yaml` 的 `runner.labels: ["windows:host"]` → `Restart-Service gitea-runner` |
| runner 一直 **Idle**,push 后任务**排队不跑** | `--labels` 不是 `windows`(最常见) | 改 `config.yaml` 的 `runner.labels: ["windows:host"]` → 重启任务(§4.4) |
| `daemon` 启动报 **connection refused / dial tcp** | `--instance` 填了不可达地址 | 删 `.runner` → 重新 `register`,`--instance http://127.0.0.1:3001` |
| 启动报 **token** 相关错误 | Registration Token 过期(约 1 小时)或已用过 | 回网页重新创建 runner 拿新 token,重新 `register` |
| 任务跑到一半报 `python: 不是内部或外部命令` | 服务 PATH 没有 Python | 确认 Python 在**系统** PATH → `Restart-Service gitea-runner` |
| `l0-gates` 报 `::error::runner 缺少:Python, cppcheck` | 同上,PATH 未生效 | 装齐 + 重启服务(§5.1) |
| 任务跑到一半报 `python: 不是内部或外部命令` | SYSTEM 账户 PATH 没有 Python | 确认 Python 在**系统** PATH → 重启任务(§5.1) |
| `l0-gates` 报 `::error::runner 缺少:Python, cppcheck` | 同上,PATH 未生效 | 装齐 + 重启任务(§5.1) |
| `checkout` 步骤卡住 / 拉不到 action | Gitea 默认从 **github.com** 拉 action,本机不通外网 | 见 §8 |
| `l05` 日志 `::warning::runner 未安装 MSVC` | MSVC 不在标准路径 | 见 §5.2 |
| `l05` 报 `fatal error C1083: 无法打开 "stdio.h"` | 缺 Windows SDK | 装 VS 时勾"使用 C++ 的桌面开发" + SDK |
| 日志里 `pre-commit` 第一次特别慢 | 首次下载各钩子环境 | 正常,`cache.enabled: true` 后第二次快 |
| **改了 `.runner` / 换机器** | 注册信息失效 | 删 `.runner` → 重新 `register` |
| `daemon install` 报 `accepts at most 0 arg(s)` | **v4 已移除该子命令** | 用 `sc.exe create` / `New-Service`(§4.2) |
| `daemon install` 报 `accepts at most 0 arg(s)` | **v4 已移除该子命令,且无任何服务子命令** | **改用任务计划程序**(§4) |
| 🔴 `Start-Service gitea-runner` 报 **无法启动服务**(错误 1053) | **`daemon` 不是服务型程序**,不向 SCM 回报 `SERVICE_RUNNING` | **删除该服务,改用任务计划程序**(§4.0 / §4.5) |
| `Register-ScheduledTask` 报 **拒绝访问** | Shell 未提权(`IsAdmin=False`) | 右键 PowerShell → **以管理员身份运行**(§4.6) |
| 任务 `LastTaskResult` 非 0 | 启动包装脚本路径/权限问题 | 看 `log\runner-stdout.log`;确认 `.cmd` 存在且为 ASCII 编码 |
| 任务跑满 72 小时被杀 | 计划任务默认 `ExecutionTimeLimit` | 设为 `0`(不限时长),见 §4.3 警示 |
| `config set log.file ...` 报 `unknown config key` | **v4 的 log 段无 `file` 键** | 用 `log.job.dir` 或输出重定向(§3) |
| `New-Service` 报 **拒绝访问** | Shell 未提权(`IsAdmin=False`) | 右键 PowerShell → **以管理员身份运行**(§4.5) |
| `New-Service` 报 `找不到与参数名称"WorkingDirectory"匹配的参数` | WinPS 5.1 的 `New-Service` 无此参数 | 去掉它,靠 `--config` 绝对路径 |
| **脚本报一堆 `源文本中包含无法识别的标记` / `字符串缺少终止符` / 中文显示成 `鐒跺悗鎵ц`** | 🔴 **`.ps1` 无 BOM,WinPS 5.1 按 GBK 解读 UTF-8** | **给脚本加 UTF-8 BOM**(§11) |
| **脚本报一堆 `源文本中包含无法识别的标记` / `字符串缺少终止符` / 中文显示成 `鐒跺悗鎵ц`** | 🔴 **`.ps1` 无 BOM,WinPS 5.1 按 GBK 解读 UTF-8** | **给脚本加 UTF-8 BOM**(§7.1) |
### 7.1 🔴 必读:给含中文的 `.ps1` 加 UTF-8 BOM
@@ -469,14 +528,14 @@ date +%s # 对比 last_online
```powershell
# 方法 A:PowerShell 重存为 UTF8BOM
$c = Get-Content "D:\Docker\act_runner\deploy_runner.ps1" -Raw -Encoding UTF8
[System.IO.File]::WriteAllText("D:\Docker\act_runner\deploy_runner.ps1", $c, (New-Object System.Text.UTF8Encoding($true)))
$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)))
```
```bash
# 方法 B:直接前缀 BOM 字节(bash/Git Bash)
cd "/d/Docker/act_runner"
for f in deploy_runner.ps1 install_service.ps1 check_env.ps1; do
for f in deploy_runner_task.ps1 check_env.ps1; do
printf '\xef\xbb\xbf' > "$f.tmp" && cat "$f" >> "$f.tmp" && mv "$f.tmp" "$f"
done
```
@@ -484,7 +543,7 @@ done
**校验**:用 PowerShell 解析器(不执行)确认语法干净:
```powershell
foreach ($f in @("deploy_runner.ps1","install_service.ps1","check_env.ps1")) {
foreach ($f in @("deploy_runner_task.ps1","check_env.ps1")) {
$errs = $null
$null = [System.Management.Automation.Language.Parser]::ParseFile(
"D:\Docker\act_runner\$f", [ref]$null, [ref]$errs)
@@ -495,8 +554,12 @@ foreach ($f in @("deploy_runner.ps1","install_service.ps1","check_env.ps1")) {
> 💡 替代方案:改用 **PowerShell 7+(`pwsh`)**,它默认按 UTF-8 读脚本、无需 BOM。
> 但本机只有 WinPS 5.1,故加 BOM 最省事。
>
> 💡 **纯 ASCII 的脚本不受影响**(`check_env.ps1` 虽含中文注释,但若全英文则无此问题)。
> 本目录三个脚本现已统一加 BOM。
> 💡 **纯 ASCII 的脚本不受影响**。本目录的 `.ps1` 均含中文注释,现已统一加 BOM。
| 日志 | 位置 |
|---|---|
| runner **自身** stdout/stderr | `D:\Docker\act_runner\log\runner-stdout.log` |
| **每个 job** 的详细日志 | `D:\Docker\act_runner\log\job\` |
**看日志**:v4 的 `log` 段**没有 `file` 键**,两种落盘方式:
@@ -509,11 +572,19 @@ log:
```
```powershell
# 方式 B:前台运行时直接重定向
# 方式 B:前台运行 / 包装脚本里重定向
.\gitea-runner.exe daemon > "D:\Docker\act_runner\log\runner.log" 2>&1
```
服务模式(sc.exe 创建的)可在**事件查看器 → Windows 日志 → 应用程序**里找来源 `gitea-runner`。
**计划任务模式下看日志(两种)**:
| 日志 | 位置 |
|---|---|
| runner **自身** stdout/stderr | `D:\Docker\act_runner\log\runner-stdout.log`(由 `run_runner.cmd` 重定向) |
| **每个 job** 的详细日志 | `D:\Docker\act_runner\log\job\` |
任务本身的历史记录:**任务计划程序 → 任务计划程序库 → `GiteaActionsRunner` → 历史记录**;
或用 `Get-ScheduledTaskInfo -TaskName GiteaActionsRunner` 看 `LastTaskResult`。
---
@@ -615,12 +686,15 @@ 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) 常驻 —— ⚠️ v4 无 daemon install,用 sc.exe(管理员 PowerShell)
sc.exe create gitea-runner binPath= '"D:\Docker\act_runner\gitea-runner.exe" daemon --config "D:\Docker\act_runner\config.yaml"' start= auto
sc.exe start gitea-runner
# 4) 常驻 —— ⚠️ daemon 不是服务型程序,必须用【任务计划程序】(管理员 PowerShell)
powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\deploy_runner_task.ps1"
# 或直接跑一键脚本(管理员 PowerShell):
# powershell -ExecutionPolicy Bypass -File "D:\Docker\act_runner\deploy_runner.ps1"
# 等价手动:
# 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
# 5) 回网页确认 runner 为 Idle → 然后(经你同意后)push 代码触发第一次 CI
```
@@ -629,9 +703,11 @@ sc.exe start gitea-runner
| 脚本 | 用途 | 需要管理员 |
|---|---|---|
| `check_env.ps1` | 环境自检(Gitea 可达 / 工具链 / MSVC / 服务) | 否 |
| `deploy_runner.ps1` | 一键部署(自检 + 装服务 + 启动 + 验证) | **是** |
| `install_service.ps1` | 只装服务 | **是** |
| `check_env.ps1` | 环境自检(Gitea 可达 / 工具链 / MSVC / 任务状态) | 否 |
| `deploy_runner_task.ps1` | **一键部署**(自检 + 清旧服务 + 建计划任务 + 启动 + 验证) | **是** |
> 早前基于 Windows 服务的 `deploy_runner.ps1` / `install_service.ps1` 已删除
> —— 那条路走不通(§4.0)。
---
@@ -639,6 +715,7 @@ sc.exe start gitea-runner
| 日期 | 变更 |
|---|---|
| 2026-10-02 | **修 `.ps1` 编码坑(实测)**:无 BOM 的 UTF-8 脚本被 WinPS 5.1 按 GBK 解读 → 中文乱码(`鐒跺悗鎵ц`)并撞坏引号配对,报 `源文本中包含无法识别的标记`/`字符串缺少终止符`。**新增 §7.1「给含中文的 `.ps1` 加 UTF-8 BOM」**(两种修法 + 解析器校验命令);排障表补该条目;三个配套脚本已统一加 BOM |
| 2026-10-02 | **按实测修正为 v4.0.1**:act_runner 已更名 **`gitea-runner`**,发布页迁至 `gitea.com/gitea/runner`。**v4 移除 `daemon install/start/stop/status`**(§4.2 改用 `sc.exe` / `New-Service`);**v4 `log` 段无 `file` 键**(§3 改用 `log.job.dir`);补 §1.3 命令集对照、§4.5 提权硬约束(`IsAdmin=False` → `New-Service` 拒绝访问)、§6.1 MySQL 直查核验、排障表 +4 条(`accepts at most 0 arg(s)` / `unknown config key log.file` / `拒绝访问` / `WorkingDirectory` 参数) |
| 2026-10-02 | 初版:针对**本机 Gitea 原生部署**(`D:\Docker\Gitea\gitea.exe` + Windows 服务 + `127.0.0.1:3001`)定制 Runner 端部署全流程。核心要点:`--instance` 用回环地址、`--labels "windows:host"` 必须精确匹配 `runs-on`、PATH 与服务账号坑、MSVC 路径约束、内网 action 拉取的零依赖改法 |
| 2026-10-02 | 🔴 **常驻方式重大修正(实测推翻)**:`Start-Service gitea-runner` 必然失败。经二进制逆向确认 `gitea-runner v4.0.1` **无任何服务管理代码**(命令集仅 `bug-report/cache-server/config/daemon/exec/register`,无 `service.go`;`OpenSCManagerW` 等符号来自 Docker SDK,非服务安装代码),`daemon` 是纯控制台程序、不向 SCM 回报 `SERVICE_RUNNING`。**§4 全节重写为「任务计划程序」方案**(新增 §4.0 根因分析、§4.2 `deploy_runner_task.ps1`、§4.3 手动命令 + 72h 超时警示、§4.5 清理遗留服务、§4.6 提权);删除失效的 `deploy_runner.ps1`/`install_service.ps1`;排障表补「错误 1053」「LastTaskResult 非 0」「72 小时被杀」3 条;拓扑图/§5.1/§7 日志/§10 TL;DR 同步更新。另修 `config.yaml` 的 `fetch_timeout` 5m→1m(超出 RPC 1m 会被截断并告警) |
| 2026-10-02 | **修 `.ps1` 编码坑(实测)**:无 BOM 的 UTF-8 脚本被 WinPS 5.1 按 GBK 解读 → 中文乱码(`鐒跺悗鎵ц`)并撞坏引号配对,报 `源文本中包含无法识别的标记`/`字符串缺少终止符`。**新增 §7.1「给含中文的 `.ps1` 加 UTF-8 BOM」**(两种修法 + 解析器校验命令);排障表补该条目;配套脚本已统一加 BOM |
| 2026-10-02 | **按实测修正为 v4.0.1**:act_runner 已更名 **`gitea-runner`**,发布页迁至 `gitea.com/gitea/runner`。**v4 移除 `daemon install/start/stop/status`**;**v4 `log` 段无 `file` 键**(§3 改用 `log.job.dir`);补 §1.3 命令集对照、§6.1 MySQL 直查核验、排障表(`accepts at most 0 arg(s)` / `unknown config key log.file` 等) |
| 2026-10-02 | 初版:针对**本机 Gitea 原生部署**(`D:\Docker\Gitea\gitea.exe` + Windows 服务 + `127.0.0.1:3001`)定制 Runner 端部署全流程。核心要点:`--instance` 用回环地址、`--labels "windows:host"` 必须精确匹配 `runs-on`、PATH 运行账户坑、MSVC 路径约束、内网 action 拉取的零依赖改法 |