この_作業中_のドキュメントは、GitHub Actionsを活用するためのベストプラクティスをまとめたものです。提案や追加があれば、ぜひGitHubでプルリクエストを送ってください!
デフォルトでは、GitHub Actionsはワークフローが6時間以内に終わらないと、それを強制終了します。多くのワークフローはそこまで時間を必要としませんが、ときには予期しないエラーが起きたり、ジョブがハングしたまま実行開始から6時間後にワークフローが強制終了されることがあります。そのため、もっと短いタイムアウトを指定することをおすすめします。
理想的なタイムアウトはワークフローごとに異なりますが、Exercismのリポジトリで使われるワークフローなら、通常30分もあれば十分です。
これには次のような利点があります。
jobs:
configlet:
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- [...]
アクションは、お気に入りのプログラミング言語の依存関係と同じように扱うべきです1。それらはExercismの管理外にある第三者の作者が書いたコードです。アクションの作者を信頼していたとしても、そのリポジトリが乗っ取られる可能性があり、そうなると間接的にExercismのリポジトリへのアクセス、それも書き込み権限まで渡してしまうことになります。
ですから、新しいアクションを導入することが本当に価値があるのか、それともコードをExercismの管理下にある(新しい)アクションに移したほうがよいのか、よく検討してください。
そのアクションが活発にメンテナンスされているかどうかも検討しましょう。たとえば、リポジトリの最近の活動を確認したり、そのアクションが個人アカウントではなく組織の一部であることを確かめたりします。
GitHubやExercismの組織によって公開されているアクションは、通常、特別な検討なしに導入しても(ほぼ)安全とみなせます。
デフォルトでは、ワークフローに与えられるアクセストークンは、読み取りと書き込みの両方について幅広い権限を持っています。
最小権限の原則は、ワークフローにも当てはめるべきです。
ワークフローが必要とする権限は、ワークフローごとに指定できます。
ワークフローが、たとえば通常のCIチェックのように、リポジトリの内容を読み取るだけで書き込む必要がない場合は、次のようにトークンを制限できます。
permissions:
contents: read
権限の完全なリストは、GitHubのドキュメントを確認してください。
他のアクションを使うときは、ブランチやタグではなく、コミット(そのSHA)に固定してください。こうすると毎回同じコードが実行されることが保証されますが、ブランチやタグに固定した場合は保証されません。
これには2つの利点があります。
このルールの唯一の例外は、Exercism自身が作ったアクションでしょう。
通常は、特定のリリースのコミットSHAに固定します。リリースのコミットSHAを探すには、アクションのリポジトリのリリースページ(例:https://github.com/actions/checkout/releases)を開きます。使いたいリリースを見つけ、リリースの左側にある概要セクションに表示されている短縮SHA(例:a12a394)をクリックします。するとリリースの詳細ページに移動し、そこで使用できる完全なコミットSHAが表示されます。
- name: Checkout code
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
ほとんどのワークフローは、GitHubがサポートするランナーで実行されます。これらのランナーを使うときは、最新バージョンではなく特定のバージョンを使います。
こうすると、ワークフローが常に同じランナーで実行されることが保証され、ビルドが_安定します_。
次のように書きます。
runs-on: ubuntu-22.04
次のように書くのではなく:
runs-on: ubuntu-latest
途中のコミットでCIを実行することは、その間に新しいコミットがプッシュされている場合、多くの場合必要でも有益でもありません。
並行実行の戦略を設定すると、同じコンテキストで実行中のワークフローを自動的にキャンセルできます。
PR内の途中のビルドをキャンセルするには、次の並行実行の設定を使います。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
上の例は、MITライセンスで公開されているPkgTemplates.jlのCIワークフローに基づいています。
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.
ここで挙げたプラクティスは、決してすべてを網羅しているわけではありません。GitHub Actionsを安全に使うための優れたセキュリティプラクティスの包括的なガイドについては、GitHubのセキュリティガイドを参照してください。
次のチェックリストを使って、ワークフローがベストプラクティスに従っているか確認できます。このチェックリストは完全であることを意図したものではなく、最も重要な項目に焦点を当てています。
その言語がnpmエコシステムを使っている場合は除きます。 ↩