Ship gate
這裡的每一條規則之所以存在,是因為一次明顯的檢查曾經回傳了一個虛假的通過。在聲明之前執行關卡,而不是之後。
根據你的堆疊調整具體內容;其形狀——什麼會使這個聲明為假?——才是可轉移的部分。
聲明規則
關於生產環境的聲明需要對生產環境進行查詢。
通過的測試不是生產環境。合併的 PR 不是生產環境。綠色的部署不是生產環境。每一項都是針對與你所斷言的系統不同的系統所做的聲明。
如果沒有人類親眼檢查過結果,那就不是「已驗證」——請說明你實際檢查了什麼。
部署驗證
- 知道什麼真正觸發了部署。 在與 git 整合的主機上,是推送(push)而不是 CLI 調用。當專案是透過推送部署時,使用 CLI 部署會產生一個不是用戶所獲得的建置版本。
- 檢查擁有專案的帳戶。 本地登入的 CLI 可能以個人帳戶進行驗證,該帳戶並不擁有生產專案——每條命令都會針對錯誤的目標靜默地成功執行。
- 使用與已部署 SHA 相關的提交狀態進行驗證,而不是只看儀表板。
- 確認是目前生產環境的部署,而不僅僅是狀態為 READY 的部署。可能同時有多個部署處於 ready 狀態。
- 邊緣/無伺服器函數與應用程式是分開部署的。 合併的 PR 不會部署邊緣函數;請明確檢查其版本。
- 僅客戶端的變更可能不需要部署函數——不要等待一個永遠不會到來的函數部署。
- 在斷言版本之前,重新獲取線上 manifest。平行工作會在你底下更新版本。
CI 驗證
- 關卡應建立在每個必要的上下文上,而不是第一個綠色的上下文。
- 絕不對管道命令設置關卡。
some-check | tail回報的是tail的退出碼,掩蓋了真正的失敗。在沒有PIPESTATUS(zsh 與 bash 在此有差異)的 shell 中,很容易出錯——請檢查命令自身的狀態。 steps: 0表示作業從未執行過,而不是它通過了。Checks API 可以為一個沒有執行任何工作的作業報告結論。- 一個可疑地快速失敗且沒有步驟的失敗,通常是帳單或權限問題,而不是 YAML 問題。
- 僅重新執行失敗的作業會重播分支的過期快照。先更新分支,然後再重新執行。
- 檢查列表會省略從未被建立的作業。 沒有失敗並不能證明有通過。
gh pr create需要明確的--base。圍繞它的鏈式 heredoc 可能會靜默地失敗。
型別與 lint 關卡
- 大型 TypeScript 專案可能需要增加 Node 堆積大小;沒有它,
tsc會以類似程式碼錯誤的方式崩潰。 - 知道你的型別檢查器和 linter 實際涵蓋哪些目錄。 邊緣函數目錄經常被兩者排除。如果它們在不同的執行環境中執行,請使用該執行環境自己的檢查器來檢查它們——測試作業不是型別關卡。
- 在工作樹或乾淨的檢出目錄中建置,而不是在帶有未提交漂移的工作目錄中。
資料庫
- 絕不隨意地對生產環境推送 schema 或執行遷移。透過專案選擇的審查路徑一次性地應用 schema。
- 在相信新的儲存程序之前,先對真實的資料庫進行呼叫。 Mock 隱藏了僅在真實型別和真實歧義中出現的執行階段錯誤。
- 如果測試套件全域 mock 資料庫,一個通過的單元測試對資料庫證明了任何事情。
- 絕不在由觸發器管理的資料欄上進行 compare-and-set——觸發器會在寫入時改變它。
- 在合併之前,衡量變更對生產資料的影響範圍。 一個針對本地種子資料看起來範圍很窄的篩選器,可能會匹配到實際資料行中非常不同的比例。
環境陷阱
- 絕不假設機器的時區——執行
date。 依賴日期的測試會在時區偏移上失敗,而且失敗看起來像是程式碼錯誤。 - 未設定的 git 身份可能會阻止部署,並表現為一個看似無關的網路錯誤。
- 從檔案設定主機環境變數,而不是使用內聯賦值;shell 和 CLI 可能會嵌入不可見的換行符,從而悄悄地破壞該值。
- 排程作業的成功不是作業影響的成功:一個 runner 回報
succeeded僅表示調用返回了,而不是工作完成了。請驗證其效果。
輸出
將每個關卡標示為 PASS(證據) 或 NOT CHECKED(原因)。
絕不暗示一個關卡已經執行而實際上並未執行。如果任何關卡失敗或未經檢查,請明確說明該變更尚未驗證——保留該聲明是正確的做法。