Skip to content

ci: 安全掃描接在基礎驗證之後,不再與它並行 - #12

Merged
hoshimoe merged 1 commit into
mainfrom
claude/codeql-security-ci-optimization-q8brpw
Aug 12, 2026
Merged

ci: 安全掃描接在基礎驗證之後,不再與它並行#12
hoshimoe merged 1 commit into
mainfrom
claude/codeql-security-ci-optimization-q8brpw

Conversation

@hoshimoe

Copy link
Copy Markdown
Member

問題:兩支 workflow 是並行的,不是「跑完才跑」

ci.ymlsecurity.yml 是兩支獨立的 workflow,同一個事件各自觸發,所以基礎驗證還在跑的時候,CodeQL 已經在跑了——實測有一次 CodeQL 比基礎驗證早 91 秒結束。

也就是說「建置紅了就別跑 CodeQL」從來沒有發生過,而四十分鐘的 timeout 是實打實會被花掉的。

CodeQL 的 autobuild 與 govulncheck 都要先建置得起來,建置壞掉時它們吐的是同一個編譯錯誤換一種包裝。一顆紅燈因此變成三顆指向同一個根因的紅燈,而多餘的紅燈只會稀釋掉真的那一顆。

修法

needs: 只在同一個 workflow 檔內成立,跨檔案表達不了順序。把 security.yml 改成 workflow_call,由 ci.yml 呼叫:

go / js(gofmt、vet、build、test;npm test)
      ↓ needs
安全掃描(CodeQL / govulncheck / Gitleaks / Trivy)

gojs 任一紅燈、或因草稿而 skipped 時,security 整組 skipped

不用 workflow_run:它只讀預設分支上的 workflow 檔(改這支檔案的 PR 驗不到自己的改動),而且它的執行不會掛回 PR 的檢查清單。本地 uses: ./… 讀的是被呼叫那一顆 commit 的檔案。

每週排程刻意留在閘門外:它回答的是「沒有動過的程式今天有沒有變成有問題的」,與 main 現在編不編得過無關;跟著 skipped 的話,一個紅著的 main 會讓掃描停擺一整週。

順帶砍掉兩個死條件

  • security.ymlconcurrency:。被呼叫時 github context 是呼叫端的,${{ github.workflow }} 會算成 "CI"——群組字串與呼叫端完全相同cancel-in-progress 為真時是同一次執行取消自己。取消語意由 ci.yml 那一層提供(被呼叫的 job 屬於同一次 run)。
  • 各 job 的草稿 if:。被呼叫的路徑上 gojs 已經擋掉草稿,排程與手動路徑上它恆真。閘門收斂到 ci.yml 一處。

檢查名稱會變

CodeQL (go)安全掃描 / CodeQL (go)GitleaksTrivygovulncheck 同理;gojs 不變。本倉庫 main 沒有分支保護,所以沒有必要檢查會因此卡住。

沒有動到零相依那條規則:這次只改 .github/workflows/go/go.modjs/package.json 未動。

驗過什麼

actionlint 全綠。綠燈本身先做了兩次負向測試(needs: 指向不存在的 job、uses: 指向不存在的檔案),兩個都被抓到,所以那個綠不是因為它沒在看。

另外斷言:觸發集合恰好是 {workflow_call, schedule, workflow_dispatch}、沒有殘留的 concurrency 與草稿 if:needs 的每個名字都是同檔案裡的 job,以及呼叫端 permissions 覆蓋得住被呼叫 job 的每一項——呼叫端是上限,給少了不是語法錯誤,是掃描全成功但 job 以 Resource not accessible by integration 收場。

沒驗到:實際跑一次 Actions。這個 PR 就是第一次。


Generated by Claude Code

`ci.yml` 與 `security.yml` 是兩支獨立的 workflow,同一個事件各自觸發,
所以它們一直是**並行**的。ShatteredRealms PR#110 的實測:CodeQL 在
13:50:11 結束,而 `verify` 到 13:51:42 才結束——建置紅燈的那些場合,
四十分鐘的 CodeQL 早就整支跑完了。

而 CodeQL 的 autobuild 與 govulncheck **都要先建置得起來**,建置壞掉時
它們吐的是同一個編譯錯誤換一種包裝。一顆紅燈因此變成三顆指向同一個
根因的紅燈,多餘的那兩顆只會稀釋掉真的那一顆。

`needs:` 只在同一個 workflow 檔內成立,所以把 security.yml 改成
`workflow_call`,由 ci.yml 以 `needs:` 呼叫。verify 紅燈、或因草稿而
skipped 時,整組掃描 skipped。

不用 `workflow_run`:它只讀**預設分支**上的 workflow 檔(改這支檔案的 PR
驗不到自己的改動),而且它的執行不會掛回那個 PR 的檢查清單。

**每週排程刻意留在閘門外**——它回答的是「沒有動過的程式今天有沒有變成
有問題的」,與 main 現在編不編得過無關;跟著一起 skipped 的話,一個紅著
的 main 會讓掃描停擺一整週。

順帶兩項:

- security.yml 的 `concurrency:` 移除。被呼叫時 github context 是**呼叫端**
  的,`${{ github.workflow }}` 會算成 "CI",群組字串與呼叫端完全相同——
  同一次執行會取消自己。取消語意由 ci.yml 那一層提供,已經涵蓋到。
- 各 job 的草稿 `if:` 移除。被呼叫的路徑上 verify 已經擋掉草稿,排程與
  手動路徑上它恆真;閘門收斂到 ci.yml 一處。

**檢查名稱會變成 `安全掃描 / CodeQL (go)`**(`verify` 那一顆不變)。
分支保護的必要檢查若按舊名字設定,要跟著改名。

驗證:actionlint 綠,並以兩次負向測試(needs 指向不存在的 job、uses 指向
不存在的檔案)確認它真的驗得到這次改動的兩個關鍵處。

記錄:workspace `todo/安全掃描接在基礎驗證之後.md`
@hoshimoe
hoshimoe merged commit 258a2bc into main Aug 12, 2026
9 checks passed
@hoshimoe
hoshimoe deleted the claude/codeql-security-ci-optimization-q8brpw branch August 12, 2026 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants