From 6ddaf752605f7f032ab2fa885204d983c1d9ddf6 Mon Sep 17 00:00:00 2001 From: OG T Date: Sun, 29 Mar 2026 02:12:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(runner):=20v5=20-=20Job=20=E5=B1=A4?= =?UTF-8?q?=E7=B4=9A=20mutex=20=E7=A2=BA=E4=BF=9D=E5=9A=B4=E6=A0=BC?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=9F=B7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因確認: - 即使有 needs 依賴,Jobs 仍可能在 "Set up job" 階段並行 - 所有 Jobs 共用同一 Runner,並行寫入 _diag/pages 造成衝突 永久解決方案: - 每個 Job 加上 concurrency.group: runner-awoooi-cd-mutex - cancel-in-progress: false (等待而非取消) - 確保同一時間只有一個 Job 在 Runner 上執行 影響: - CD 會變慢 (Jobs 嚴格序列) - 但保證穩定性 (不再有檔案衝突) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/cd.yaml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index bd348d24..4c82c521 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -57,6 +57,11 @@ jobs: name: "Pre-flight Check" runs-on: [self-hosted, harbor, k8s] timeout-minutes: 1 + # 2026-03-29: Runner 全局 mutex,確保同一 Runner 不會並行執行任何 CD Job + # 使用固定 group 名稱 (非 run_id),所有 CD Jobs 共用同一把鎖 + concurrency: + group: runner-awoooi-cd-mutex + cancel-in-progress: false steps: # ======================================================================= # 2026-03-29: Runner _diag/pages 檔案衝突修復 (v3) @@ -130,6 +135,9 @@ jobs: runs-on: [self-hosted, harbor, k8s] needs: pre-flight-check timeout-minutes: 1 + concurrency: + group: runner-awoooi-cd-mutex + cancel-in-progress: false outputs: api: ${{ inputs.force_deploy == true && 'true' || steps.filter.outputs.api }} web: ${{ inputs.force_deploy == true && 'true' || steps.filter.outputs.web }} @@ -168,7 +176,10 @@ jobs: name: "Build API" runs-on: [self-hosted, harbor, k8s] needs: detect-changes - timeout-minutes: 20 # 2026-03-29: 增加超時時間 (Docker Build 需要更長時間) + timeout-minutes: 20 + concurrency: + group: runner-awoooi-cd-mutex + cancel-in-progress: false if: | !inputs.skip_api && ( needs.detect-changes.outputs.api == 'true' || @@ -208,7 +219,10 @@ jobs: name: "Build Web" runs-on: [self-hosted, harbor, k8s] needs: detect-changes - timeout-minutes: 20 # 2026-03-29: 增加超時時間 (Next.js Build 需要更長時間) + timeout-minutes: 20 + concurrency: + group: runner-awoooi-cd-mutex + cancel-in-progress: false if: | !inputs.skip_web && ( needs.detect-changes.outputs.web == 'true' || @@ -261,6 +275,9 @@ jobs: runs-on: [self-hosted, harbor, k8s] needs: [detect-changes, build-api, build-web] timeout-minutes: 10 + concurrency: + group: runner-awoooi-cd-mutex + cancel-in-progress: false if: always() && (needs.build-api.result == 'success' || needs.build-api.result == 'skipped') && (needs.build-web.result == 'success' || needs.build-web.result == 'skipped') environment: production steps: