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:
6
.github/workflows/cd.yaml
vendored
6
.github/workflows/cd.yaml
vendored
@@ -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
|
||||
|
||||
@@ -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 分鐘自動清理過期的診斷檔案:
|
||||
|
||||
Reference in New Issue
Block a user