GitHub ActionsでCI盆栽
CI/CDのタスクをいい感じにしていく活動は常に行っていたい(気持ち)
さて、本稿はGitHub Actionsの利用を前提としてCIについて色々書く。
CD版もあとで作る(というか記事構造いい感じに整理する)。
## どうあるべきか
実行が高速であり、開発生産性を低下させない
コストが組織にとって認容可能な程度に安価である
ソースコードから静的に解析可能なバグを検出することができる
自動テストはすべてCIランタイムで再現される
確率的な問題が生じず、コードベースが共通(commit hashが同値)であるなら冪等に動作する
セキュリティ的な懸念事項が運用以前に精査されている
## Howとか
高速化
依存関係(パッケージ)はキャッシュする
「.lock的なファイルのハッシュをキャッシュキーにして、artifactsとしてupload。次回実行時には、キーが一致していればインストールをスキップして、artifactsからDLしたキャッシュを用いる」というような仕方で構築しておくと、エコである
並列で実行可能なjobを並列化する
ただしコスト観点・責務観点での妥当性は検査すること
コスト
実行時間課金なので、高速化もコスト対策になり得る
が、jobを並列させて高速化する場合はむしろコストを高めてしまう
jobごとの実行時間に課金されるためであり、インスタンス立ち上げにかかるオーバーヘッドが主な増分
workflowごとに、何をフックにするかを整理する。例えば、同じCIでも以下のような温度差の違いが発生し得る
default branch向き以外ではやらなくてもいい
commitごとに常に検査したい
commitごとに検査するCI Workflowは、concurrencyオプションを利用して、HEADの更新に合わせて自動中断をする
code:yaml
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
静的解析
使っている言語環境でデファクトスタンダートとなっているツールは回すようにする
フォーマットが掛けてあるかどうかも検査していいが、場合によってはストレスが溜まるので、なるべく引っかからないような状態をローカル開発環境含めて作っていくべき
もちろん、ビルドを伴う言語の場合はビルドを行うこと
ユニットテストの再現性
と言っても、あまり書くことはないが
確率的な問題
ユニットテストがランダム落ちしている場合は、修正PRを出す
安定性が低い外部アクセス系には、適宜リトライ機構を用いる
例えば自分のCI環境ではopenapi-generatorを都度取得しているが、これがたまに落ちるので自動リトライを掛けている
↑この都度取得もそもそもなくしたいが、self-hosted runnerが使えない場合は仕方ない
セキュリティ
Workflowに必要以上の権限を与えない
資格情報類はSecretsに管理するか、IaaS系のSecrets Store(ex: AWS SSM PS)などで管理する(Actions以前の話)
そもそもGitHub Organizationの管理が真っ当になされている(Actions以前の話)
個々のプロジェクト参加者が2FAを設定している状況を作る(Actions以前の話)
### 小ネタ
git submodulesを使っている場合、checkout用のステップは再利用性のために切り出しておくと良い
職場がリッチでGitHub Enterpriseとかできる場合、self-hosted runnerに依存ツールを詰めておくとさらに速くできる
「ユニットテストの結果だけさっさと確認したい」という気持ちが発生することも多い。コスト面が許すなら、解析系・ユニットテスト系でWFを分けてしまうのもひとつの手段だ
### 参考になりそうな記事ストック
メルカリのGitHub Actionsのセキュリティガイドライン
野村友規さんのGitHub Actions本
同氏のOrganization運用本(Zenn)
同氏のComposite Action本(Zenn)