Github Actionsを使うために知っておきたいこと

はじめまして、株式会社マクアケでエンジニアをしている@tokutoku3です。

この記事は [Makuake Advent Calendar 2020](https://adventar.org/calendars/5986) 9日目の記事です。（大遅刻)
弊社では主なCIツールとしてCircleCIを導入しているのですが、新規リポジトリでGithub Actionsを試したので、ざっくりとした比較と使う際に意識しておきたいポイントについて共有できればと思います。

# Github Actionsとは？

Github上で実行/管理/確認ができるワークフローの自動化サービス。
2018年10月頃に発表され、2019年11月頃に一般利用可能となったそうです。

てっきり最初からCI/CDのツールとして打ち出されていたのかと思っていたのですが、
ベータ版での開発者FBを受けて、CI/CDの機能も持つようになった経緯があるみたいです。

> 参考
> https://it.impress.co.jp/articles/-/18412


# 導入

初見の人は、まず公式ドキュメントの下記を読むのが一番だと思います。

* [Github Actions 入門](https://docs.github.com/ja/free-pro-team@latest/actions/learn-github-actions/introduction-to-github-actions)
* [Github Actions クイックスタート](https://docs.github.com/ja/free-pro-team@latest/actions/quickstart)

他にもいろいろなユースケースがわかりやすくまとまっているので、
基本的には公式ドキュメントを読めば大抵のことは解決できました。



# CircleCIとの比較

基本の概念が大体おなじようなものなので、
CircleCiを使っていた人がGithub Actionsを試す場合はすんなり理解できる印象でした。


## 基本の概念

Github Actionsの場合はworkflow単位でファイルを分割できるのがわかりやすくて良かったです。

* CircleCI
  * 処理のまとまりを **Job** と呼ぶ
      * Job内の各処理を **Step** と呼ぶ
  * Jobの実行順、直列/並列などの制御を **Workflow** で管理する
  * 拡張機能が **Orbs** として提供されている
      * Slack通知、AWS連携、etc
* Github Actions
  * 処理のまとまりを **Job** と呼ぶ
      * Job内の各処理を **Step** と呼ぶ
  * Jobの実行順、直列/並列などの制御を **Workflow** で管理する
  * 拡張機能が **Actions** として提供されている
      * [Github marketplace](https://github.com/marketplace?type=actions) で探せる。Orbsに比べて玉石混合な印象が強い
      * [簡単にmarketplaceにActionを公開できてしまう](https://docs.github.com/ja/free-pro-team@latest/actions/creating-actions/publishing-actions-in-github-marketplace) ので、非officialなActionを使う場合セキュリティ面に問題ないか確認はしたほうがよさそう

## ビルドが実行されるタイミング

手動実行できたり、Pull-Request作成をトリガにする方法がデフォルトで入っているのが嬉しい..!

* CircleCI
  * 基本
      * 対象のリポジトリにbranch/commitがpushされた時
      * スケジュールされたタイミング
      * API経由で実行した時
  * filterやignoreなどを指定することである程度実行ブランチを制御できる
* Github Actions
  * 基本
      * CircleCIと同じタイミング + 下記
      * 手動実行した時
      * [Github上で発生する様々なイベント](https://docs.github.com/ja/free-pro-team@latest/actions/reference/events-that-trigger-workflows)
          * PR作成時、コメントされた時、タグがつけられたとき、forkされたとき、etc
  * 実行ブランチの他、特定のディレクトリ/ファイルの変更のみに制限することもできる

## 実行制御のバリエーション

Github Actionsは並列実行にまだ難あり、という印象でした。

* CircleCI
  * workflowのrequired句を使って実行順を制御できる
      * required句に複数jobを指定することで並列実行の結果待ちができる
  * parallelismを指定することで単一jobを並列実行できる
  * 実行順をグラフィカルに確認できる
* Github Actions
  * jobのneeds句を使って実行順を制御できる
      * needs句に複数jobを指定することで並列実行の結果待ちができる
  * matrix機能を使うことでなんちゃって並列実行ができる
      * jobに渡す引数を分けて実行範囲を分割するイメージなので、CircleCIの使い勝手とはかなり異なる
  * 実行順をグラフィカルに確認 **できない**
      * ...できなかったのですが、本記事を公開(する予定だった)日である12/9にアップデートされ、CircleCI同様jobの実行順がグラフィカルに確認できるようになりました🎉
![スクリーンショット 2020-12-27 17.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199813/b950adc8-fb64-d834-3da7-edc75405bd63.png)

## 実行環境

Jobごとの実行環境になにを指定できるか、という観点です。
Github Actionsの場合は１つのjobで複数のDocker imageを扱うことができます。

* CircleCI
  * Linux(machine)、MacOS、WindowsOS
  * Docker image
* Github Actions
  * Ubuntu、MaxOS、WindowsOS
  * Docker imageを **ベースの実行環境としては指定できない**
      * Actionの処理をDockerに実行させることで任意の環境を使うことが可能

## 成果物の保存

ここは使い勝手一緒。

* CircleCI
  * アーティファクトとして指定したパスのファイルを保存できる
  * ビルドページからアーティファクトの確認とDLができる
* Github Actions
  * CircleCIと同じ

## キャッシュ

Jobを跨いでビルドしたファイルを共有したり、実行速度を改善するために使います。
アーティファクト同様使い勝手はほぼ一緒でした。

* CircleCI
  * save_cache / restore_cache を使って key-file形式のキャッシュを作成/参照できる
  * 段階キャッシュが使える
* Github Actions
  * actions/cache を使って key-file 形式のキャッシュを作成/参照できる
  * 段階キャッシュが使える
      * CircleCIの記法と大体同じ
     
```yml
- name: Cache node modules
  uses: actions/cache@v2
  env:
    cache-name: cache-node-modules
  with:
    # npm キャッシュファイルは Linux/macOS の「~/.npm」に保存される
    path: ~/.npm
    key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-build-${{ env.cache-name }}-
      ${{ runner.os }}-build-
      ${{ runner.os }}-
```

## SSHデバッグ

一応どちらもできる。

* CircleCI
  * **Rerun Job with SSH** ボタンで再実行すると実行コンテナの接続情報が表示される
* Github Actions
  * 標準では提供されていない
  * [action-tmate](https://github.com/mxschmitt/action-tmate)など、Actionsとしてその機能が提供されているものを使う

## ローカル検証

Github Actionsについては、バリデーションもactでできるようになれば完璧！
とはいえ覚えることはそこまで多くないので、今の時点でも十分つかえました。

* CircleCI
  * circleciコマンドを利用できる
      * Macの場合は `brew install circleci`
  * 設定ファイルのバリデーションやローカルでの実行検証ができる
* Github Actions
  * 公式提供のものはまだない
  * ローカル実行検証については [act](https://github.com/nektos/act) を利用できる
      * Macの場合は `brew install act`
  * 簡易的なバリデーションとしても使えるが、 `circleci validate` ほどわかりやすくはない
  * Github上のworkflow editorにコピペすれば詳細なシンタックスエラーが分かる


# Github Actions運用時に気をつけたいこと

知らずに使って「あれ？」となったポイントをいくつか。

## ワークフローのグループ分けができない

ワークフローをグルーピングする機能は記述時点ではありません。
せっかくworkflowをファイル分割して管理できるので、タブとかリストで表示も管理できるようになると嬉しいな...。

ワークフロー名のa-z順に並ぶので、直近たくさん作る場合はprefixの設計が大事になりそうです。
![スクリーンショット 2020-12-09 15.43.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199813/e359cccd-0991-ea4c-38e1-c8320ba31244.png)


## 実行時に入力したパラメータが出力されない

workflow_dispatch(手動実行を可能にするオプション)でinputsパラメータを使うときに考える必要のある問題です。

入力したパラメータがビルド結果にのこらないため、
inputsをechoするだけのjob(step)があった方が調査などに役立ちそうです。

```yml
on:
  workflow_dispatch:
    inputs:
      releaseTag:
        description: 'リリース対象のタグを入力して下さい'
        required: true
        default: ''

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo ${{ github.event.inputs.releaseTag }}
```

## 手動実行時に選択できるbranchを制限できない

master(main)ブランチだけで動かしたいワークフローでも、違うブランチを選択することができてしまいます。
そのため、job定義側で「対象のブランチかどうかをチェックして、違ったら何もしない」のような制御が必要です。

## 一部の情報が確認しづらい

Github Actionsの一覧画面では実行されたbranch、実行日、実行時間などが表示されるのですが、
手動実行した場合、指定されたブランチはなぜか一覧画面に表示されません。
(実行結果の詳細ページに行くと記載されている)

また、Jenkinsでいう実行時間推移のようなグラフはありません。

## アーティファクトの利用は課金の対象

実行結果の保存などで使いたくなりますが、こちらはプランごとに無料で使えるサイズが決まっています。
基本的に残り続けるので、自動削除の設定を入れるか、本当に必要なタイミングでのみ使うようにしたほうが良さそうです。

# 料金形態について

「無料枠を超えると従量課金」がベースの方針で、かなりお安い印象です。

## 基本の話

* Githubの契約プランごとに無料で使える枠が決まっている
  * Github Actionsの総実行時間 (分)
  * Github Storageの総使用量 (GB)
* 無料枠を超えると従量課金
  * 支出制限の設定ができ、デフォルトだと $0
  * なので無料枠超えるとGithub Actions使えなくなる

## プランごとに無料枠が異なる

ドキュメントに記載があるので、利用を検討している場合は目を通しておくと良いでしょう。

* [GitHub Actionsの支払いについて
](https://docs.github.com/ja/free-pro-team@latest/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions)

# まとめ

* CircleCI使ってた人ならすんなり導入できる
* Githubの細かいイベントをトリガに処理を動かせるので夢がひろがる
  * release tag打ったら自動でnpm packageをpublishするとか
  * PR作成されたらテスト実行して結果をコメントさせるとか
* 手動実行できるのが地味に嬉しい
  * それができないからJenkins使う、という状況を脱却できる
* とはいえ痒いところに手が届ききってない感じ
  * 今後のアップデートに期待

やたら安いので、初めてCI/CDツールを導入しようと思っている人や、コスト削減を検討している人にとっては採用しやすいサービスかなと思います。

また、アップデートの速度もかなり早く「ここがちょっと使いづらいんだよな...」と思っていた箇所がいつの間にか改善されてたりするので、**本記事のTipsも半年後には全部標準で提供されているかもしれません。**
(それはそれで楽しみですね)

それでは、よいGithub Actionsライフを！