GitHub Actions:最佳實務


這是一份_持續更新_的文件,用來彙整使用 GitHub Actions 的最佳實務。 如果你有任何建議或想補充內容,歡迎到 GitHub 上開一個 pull request!

最佳實務彙整

為工作流設定逾時

預設情況下,如果工作流在 6 小時內沒有完成,GitHub Actions 就會把它終止。 許多工作流根本不需要這麼長的時間就能跑完,但有時會發生非預期的錯誤,或是某個作業就這麼卡住,直到工作流開始執行 6 小時後才被終止。 因此建議設定較短的逾時時間。

理想的逾時時間取決於個別工作流,不過對 Exercism 儲存庫裡的工作流來說,30 分鐘通常已經很夠用。

這樣做有以下好處:

  • PR 不會花半天的時間卡在等待 CI,問題可以及早發現,或是重新啟動工作流執行。
  • 整體的平行建置數量有限,只要及早取消,卡住的作業就不會對其他 PR 造成影響。

範例

jobs:
  configlet:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    steps:
      - [...]

考慮是否真的需要(第三方)動作

你慣用程式語言裡的相依套件該怎麼看待,動作就該怎麼看待1,它們是由 Exercism 無法控管的第三方作者所寫的程式碼。 即使你信任該動作的作者,儲存庫仍可能遭到惡意接管,間接讓那些人取得 Exercism 儲存庫的存取權,包括寫入權限。

因此,你應該仔細考慮引入新的動作是否真的值得,或者把程式碼搬進 Exercism 掌控下的(新)動作會不會更好。

也要考慮該動作是否仍有在積極維護,例如查看儲存庫近期的活動情形,或確認該動作隸屬於某個組織,而不是個人帳號。

由 GitHub 或 Exercism 組織發布的動作,通常可以視為還算安全,不需要特別斟酌就能採用。

限制工作流權杖的範圍

預設情況下,賦予工作流的存取權杖擁有範圍廣泛的權限,讀取和寫入都包含在內。

最小權限原則也應該套用到工作流上。

你可以針對個別工作流指定它需要哪些權限。

範例

如果某個工作流只需要讀取儲存庫的內容,而不需要寫入,例如它只是一般的 CI 檢查,就可以像下面這樣限制權杖:

permissions:
  contents: read

完整的權限清單請見 GitHub 文件。

將動作固定到 SHA

使用其他動作時,請將它們固定到某個 commit(透過其 SHA),而_不要_固定到分支或標籤。 這樣可以確保每次執行的都是同一份程式碼,而固定到分支或標籤就無法保證這一點。

這有兩個好處:

  1. 讓你的建置保持_穩定_
  2. 防止攻擊者把分支或標籤改成指向惡意程式碼

這條規則唯一的例外,可能是我們(Exercism)自己開發的動作。

尋找 commit SHA

一般來說,你會想固定到某個特定版本的 commit SHA。 要找到某個版本的 commit SHA,請前往該動作的儲存庫版本頁面(例如 https://github.com/actions/checkout/releases)。 找到你想使用的版本,然後點擊版本左側摘要區所列的簡短 SHA(例如 a12a394)。 接著你會重新導向到版本詳細資料頁面,那裡列出了你可以使用的完整 commit SHA。

範例

- name: Checkout code
  uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846

將測試執行器固定到版本

大多數工作流會在 GitHub 支援的執行器上執行。 使用這類執行器時,請指定特定版本,而不要用最新版本。

這樣可以確保工作流永遠在同一種執行器上執行,讓你的建置保持_穩定_。

範例

請這樣寫:

runs-on: ubuntu-22.04

而不要寫成:

runs-on: ubuntu-latest

考慮設定並行策略

如果期間已經推送了更新的 commit,對中間的 commit 執行 CI 通常既不必要也沒有幫助。

你可以設定並行策略,自動取消同一個情境下正在執行的工作流。

範例

如果想取消 PR 中中間的建置,可以使用下列並行設定:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
第三方聲明

The example above is based on PkgTemplates.jl's CI workflow, published under the MIT license:

MIT License

Copyright (c) 2017-2020 Chris de Graaf, Invenia Technical Computing Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

考慮真正需要哪些觸發條件

閱讀「Security hardening for GitHub Actions」指南

上面提到的做法並不完整。 如果想全面了解安全使用 GitHub Actions 的良好安全性實務,請參閱 GitHub 的安全性指南。

工作流檢查清單

你可以用下面的檢查清單,確認某個工作流是否遵循最佳實務。 這份清單並不求完整,而是聚焦在最重要的項目上。

可直接複製的版本,例如用在 PR 上

  1. 除非該語言使用 npm 生態系。 ↩