GitHub Actionsを使ってCIを実現する

# 個人環境でもCIを使いたい

仕事でCI環境を使っていて大分慣れてきた為に、個人で何かやる時も環境がないと不安になるようになってきた。
GitHub Actionsを使うと簡単に実現できるらしく、試してみたので備忘録兼ねて残しておく。

## Freeプラン(無料)で使える範囲

GitHubはFreeプランで使っているので、無料で使える枠を調べてみた。
[公式のドキュメント](https://docs.github.com/ja/billing/managing-billing-for-github-actions/about-billing-for-github-actions)によると、Freeプランでつかえる条件は次のような感じらしい。

- パブリック(公開)リポジトリ若しくはセルフホストのランナーだと、無条件に無料で利用できる。
- プライベート(非公開)リポジトリは、GitHubアカウント単位で**2000分/月**まで無料で利用できる。

個人ユースだと大抵パブリックでも問題はないが、そのうち仕事でも使うかもしれないので、プライベートでのユースについても少し調べる。

プライベートリポジトリでActionsを実行した後に、詳細画面上部に表示されるsummaryに表示される`Billable time`が課金対象の時間のようだ。
ちなみに、パブリックリポジトリだと`Billable time`の項目自体が表示されない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/07c63f4a-27b3-523c-a7dd-73db9777ed80.png)
この時間の月辺りの合計が2000分まで無料で使えるということ。
ただし、ランナーに指定するOSによって、この時間に倍率がかかるらしい。

|OS|倍率|
|:--|:--:|
|Linux|x1|
|Windows|x2|
|macOS|x10|

上で例示したワークフローを**Linuxで実行すると22s無料枠を消費する**が、**macOSで実行すると220sの無料枠を消費してしまう**ということのようだ。
Linterのような、特段OS依存性を気にしなくていいジョブであれば、Linuxを使っておくと節約になる。

現時点での利用状況は、公式ドキュメントの[GitHub Actions の使用状況を表示する](https://docs.github.com/ja/billing/managing-billing-for-github-actions/viewing-your-github-actions-usage)で説明されている手順で確認できる。

## ワークフローを設定する

自動化したい一連の流れを**ワークフロー**といい、GitHub ActionsではYAMLファイルで定義する。

ワークフローを未定義の状態でActionsのタブを開くと、こんな感じにテンプレを用意してくれているものから選択することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/c663e2b8-45c3-52dd-c30d-5c7caee5e4bd.png)
リポジトリの内容に応じて、推奨するテンプレを上位に表示してくれているようで、`Set up this workflow`をクリックすれば、こんな編集画面に遷移する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/8d653b5f-d135-4e6c-7235-43fab5eb595b.png)
ここで必要に応じて内容を編集し、いい感じなら右上の`Start commit`をクリックすると、リポジトリルートに`.github/workfrows/***.yml`が追加されたコミットが行われる。(***は編集画面で設定した任意のファイル名)
以降は、このファイルを編集すれば色々なワークフローを実現できるようになる。

YAMLファイルの構文については、公式ドキュメントの[リファレンス - ワークフロー構文](https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions)に詳しく載っているので、テンプレの構文と合わせて参考にすると良い感じ。

### CIでやりたいこと

CIで自動化したいことは、運用ルールによって異なると思うが、以下の4つあたりが多い気がする。

- ユニットテストの実行
- カバレッジの測定
- コーディング規約のチェック
- 循環複雑度のチェック

これらをワークフローに組み込むと、こんな感じの実行ステップになる。

1. リポジトリのクローン・チェックアウト
1. 実行環境の構築
1. ユニットテストの実行
1. カバレッジの測定
1. コーディング規約のチェック
1. 循環複雑度のチェック
 
この各ステップをYAMLファイル上に、実行コマンドで定義していく。
これらを1つのjobで設定しても良いが、途中のステップでコケると以降が実行されないので、独立性が高い5,6辺りは別jobにしてしまうのもアリだと思う。

### トリガを決める

ワークフローを実行するトリガも同じYAMLファイル内で定義する。
主には、統合ブランチへの**プッシュ**または**プルリク**で実行させたいケースが多いと思われるので、こんな設定になると思われる。

```yaml
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
```

mainブランチをリリース専用にして、メインラインとしてdevelopブランチを用意している場合は、こんな感じになりそう。

```yaml
on:
  push:
    branches: [ develop ]
  pull_request:
    branches: [ main, develop ]
```

この辺りの設定は、ブランチの運用ルールによって結構変わるので、リポジトリ毎にルールに見合った設定を逐次やる感じになる。
ちなみに、`push`,`pull_request`はトリガが不要なら丸ごと消せばいい。例えば`develop`ブランチだけでやりくりする場合は、`pull_request`の項はいらないとか。

## READMEにバッジをつける

最新のテスト結果のステータス表示とリンクとして、バッジを使うことができる。

Actionsのワークフローを選んで、右上の`・・・`から`Create status badge`をクリックすると、バッジの設定画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/c0425d05-c7ba-edf2-b576-f56798f67076.png)

ここで、対象のブランチやイベント(プッシュやプルリクなど)を選ぶと、それに対応したバッジのリンクが作られるので、`Copy status badge Markdown`をクリックすれば、クリップボードにMarkdown書式でバッジのリンク付き画像がコピーされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/7a6af747-a6db-99b6-d126-b0e0a3d7995e.png)

後は、これをREADME.mdとかにペーストするだけで、こんな感じにREADME上にバッジを貼れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291298/7ef4aa59-7339-bbf2-5426-ddd3083a7dbf.png)

## まとめ

GitHubアカウントさえ持っていれば、とてもお手軽にCI環境が作れていい感じ。
公式ドキュメントも割と充実しているので、使い方で困ることはそんなになさそう。
プライベートリポジトリだと無料枠の上限があるが、個人ユースでちょこっと使ってる分には、多分上限行かないと思う。
codeCovを合わせて使うと更に便利だったので、そちらの記事も書きたいなぁ。

## 参考

- [GitHub Actions 公式ドキュメント](https://docs.github.com/ja/actions)
- [Github Actions 8ヶ月使ってみてわかったことまとめ](https://qiita.com/bigwheel/items/2ab7deb237122db2fb8d)
- [GitHubの新機能「GitHub Actions」で試すCI/CD](https://knowledge.sakura.ad.jp/23478/)