iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0

前言

昨天結尾說到,這幾天做的 review 都有一個共同問題:全都要我記得做。當步驟越來越多,就容易漏掉,所以今天把檢查搬進 CI。

但在搬之前要先討論

這個檢查,真的檢查得到東西嗎?


一個閘門要成立,得同時滿足三件事

  1. 它真的在檢查東西——不是空跑
  2. 它擋得住——違規時 exit code 非 0
  3. 它不會因為擋住而被調低

三種失敗的 CI

1. 它沒在檢查

前端有一條規矩寫在 CLAUDE.md:vitest 走 esbuild,只剝型別不檢查型別,所以測試綠了之後必須另外跑 npx tsc --noEmit。

我用一個型別錯誤驗證這條規矩,四種寫法的 exit code:

指令 exit 抓到 TS2339
npx tsc --noEmit 0 ❌
npx tsc -b 2 ✅
npm run typecheck 2 ✅
npm run build 2 ✅

第一列就是文件裡寫的那一條。原因在根目錄的 tsconfig.json——它是 Vite 範本給的 project-references 結構,"files": [],所以不帶 -p 的 tsc 沒有輸入。「沒有東西要檢查」不是錯誤,它就安靜地 exit 0。

一個永遠通過的檢查,比沒有檢查更糟。

解法:每加一道閘門,就種一個它應該抓到的錯,確認它真的紅。 這跟 TDD 的 RED 是同一件事,只是對象從程式換成 CI。

2. 它不會擋

前端裝了 oxlint。跑一次,它印出一則違規,然後 exit code 是 0。如果就這樣放進 CI,它會忠實地把訊息印在 log 裡,然後綠燈亮起。第二則也一樣,第十則也一樣。

沒人讀的 warning 是沒有效果的。

解法:一個檢查放進 CI 之前,先回答「它紅的時候我會停下來嗎」。 答案是否,就不要放。

3. 它被調低

最經典的一種,而且它看起來最有道理。

這個專案的測試跑完會印 999 個 warning,沒有人讀。既然沒人讀,那就讓它擋——pytest -W error。第一次跑:

58 failed, 17 passed, 38 errors

96 個工作單元瞬間壞掉。這時心裡冒出來的第一句話一定是「這條太嚴格了」,而把它調低只要刪一行。

但先看那些 warning 是什麼:999 個全部是同一件事——.env 裡沒設 JWT_SECRET,吃到程式裡的預設值,而那個值只有 21 bytes,低於 HMAC-SHA256 的建議下限。

補一行進 .env,96 變 1。剩下那一條是刻意用假鑰匙簽偽造 token、驗系統會不會拒收的測試——它的 warning 是對的,偽造的鑰匙本來就不該合格。所以放行寫在那一條測試上:

@pytest.mark.filterwarnings("ignore::jwt.warnings.InsecureKeyLengthWarning")
def test_a_token_signed_with_another_secret_is_refused(...):

最後是 113 passed、零 warning。

門檻要放行,只能放行具體的那一個點,而且要寫得出理由,不是回去放寬全域設定。

解法:擋住的時候先問一句——是門檻錯了,還是東西錯了? 這跟昨天那個「這條測試紅掉,是因為需求變了,還是我把需求做壞了」是同一個問題。今天這次,999 個裡面 998 個是東西錯了。


三種失敗怎麼驗證

三者的症狀都是綠燈,但驗證方式不一樣:

失敗模式 怎麼驗
沒在檢查 種一個它該抓到的錯,看它紅不紅
不會擋 看 exit code,不要看輸出
被調低 翻 git log:這條門檻的設定值,歷史上只往上動過嗎

第三條之所以要翻歷史,是因為它當下看不出來——一條被調低過的門檻,跟一條本來就訂得很鬆的門檻,設定檔上長得一模一樣。


這個專案現在的閘門

閘門 擋什麼
alembic upgrade head migration 本身壞掉——測試走 create_all,從來不碰 migration
alembic check 模型與 migration drift
pytest(warning = error) 測試 + 所有 warning
npm run typecheck 型別(不是 npx tsc --noEmit)
oxlint --deny-warnings lint
npm run test · npm run build 前端行為 + 打包

結論

  • 輸出不是閘門。 會印訊息但 exit 0 的檢查跟沒放一樣。放進去之前先問「它紅的時候我會停下來嗎」。
  • 門檻放行只能放行具體的那一點,並且要附理由。
  • 開閘門的成本是判斷,不是修。 而判斷是唯一不能外包的那一半。

明天:一張工作單元交付完之後文件回填、決策記錄、issue 收尾。


上一篇
Day 25|AI Code Review 的正確用法,以及怎麼驗證 review 本身
下一篇
Day 27|交付收尾
系列文
30 天打造我的 AI 開發工作流:從需求分析到上線 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言