fix(runner): v4 - 啟用 cancel-in-progress 防止並行衝突

根因確認:
- _diag/pages 衝突發生在 "Set up job" 階段
- 這是在任何自定義步驟執行之前
- Runner 內部 bug,workflow 層清理無法解決

永久解決方案:
- cancel-in-progress: true (確保同一時間只有一個 workflow)
- 不再嘗試清理 RUNNER_TEMP (會破壞其他 Job)
- 保留 _diag/pages 清理作為輔助措施

更新 ops/runner/README.md:
- 完整根因分析
- v3 最終解決方案說明
- 警告: 不要清理 RUNNER_TEMP

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-29 02:10:17 +08:00
parent 08fb6c59c8
commit 07114f9181
2 changed files with 28 additions and 11 deletions

View File

@@ -36,8 +36,10 @@ on:
concurrency:
group: cd-${{ github.workflow }}-${{ github.ref }}
# 2026-03-26: 改為等待而非取消,避免 Runner _diag/pages 檔案衝突
cancel-in-progress: false
# 2026-03-29: 改取消,因為 Runner _diag/pages 衝突發生在 Set up job 階段
# 等待模式 (cancel-in-progress: false) 會導致並行 Job 寫入同一診斷檔
# 取消模式確保同一時間只有一個 workflow 在執行
cancel-in-progress: true
env:
REGISTRY: 192.168.0.110:5000

View File

@@ -6,25 +6,40 @@
Error: The file '/home/wooo/actions-runner-awoooi/_diag/pages/xxx.log' already exists.
```
### 根因
- GitHub Actions Runner 在執行 Job 時會寫入診斷日誌
- 並行 Job 或快速連續執行可能產生 UUID 碰撞
- 前次執行的殘留檔案未清理
### 根因分析 (2026-03-29 完整診斷)
### 解決方案
1. **發生時機**: "Set up job" 階段 (在任何自定義步驟之前)
2. **原因**: GitHub Actions Runner 內部 bug
- Runner 在 Job 初始化時寫入 `_diag/pages/*.log`
- 並行執行的多個 Job 可能寫入相同的 UUID 檔案
- 這發生在我們的清理步驟執行**之前**
3. **次要問題**: `RUNNER_TEMP` 共享
- `_work/_temp/_runner_file_commands` 在所有 Jobs 之間共享
- 清理此目錄會導致 "Missing file at path" 錯誤
#### 1. CD Workflow 修復 (即時生效)
每個 Job 開始前強制清理並重建 `_diag/pages` 目錄:
### 解決方案 (v3 - 最終版)
#### 1. Workflow Concurrency (核心修復)
```yaml
concurrency:
group: cd-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # 必須為 true
```
**關鍵**: `cancel-in-progress: true` 確保同一時間只有一個 workflow 在執行
#### 2. Job 層清理 (輔助)
每個 Job 開始時只清理 `_diag/pages`**不碰** `RUNNER_TEMP`
```yaml
- name: "Clean Runner Diagnostics"
run: |
RUNNER_ROOT=$(dirname "$(dirname "$RUNNER_TEMP")")
rm -rf "$RUNNER_TEMP"/* "$RUNNER_ROOT/_diag/pages" .claude/worktrees 2>/dev/null || true
rm -rf "$RUNNER_ROOT/_diag/pages" .claude/worktrees 2>/dev/null || true
mkdir -p "$RUNNER_ROOT/_diag/pages" 2>/dev/null || true
```
**關鍵**: 刪除整個目錄再重建,而非 `rm -rf _diag/pages/*`
**警告**: 絕對不要清理 `$RUNNER_TEMP/*`,會破壞其他 Job 的內部通訊
#### 2. Systemd Timer (背景清理)
每 5 分鐘自動清理過期的診斷檔案: