このブログのCIをCircleCIからGitHub Actionsに移行しましたので、備忘のために作業時のメモを(補足を添えて)公開します。

動機

GitHub ActionsをCIとして業務利用できるかどうか体感で確認したかったためです。

要件

  • developmentブランチへのpushをトリガーにRaketaskを実行し、jekyllによって静的サイトを生成する
  • 生成された静的サイトをmasterブランチへpushする
  • 直近のビルド成功時のCommitと比較し、/_posts/以下に差分がある場合はindexを生成しAlgoliaサーバにアップする

やったこと

  • /.github/workflowsディレクトリを作成する(命名固定)
  • ディレクトリ以下にGithub Actionsのconfigファイルを作成する(命名は自由なのでdeploy.ymlとする)
  • deploy.ymlにCircleCI用のconfigファイルの内容を移植する
  • ビルドがSuccessした直近のcommit hashを特定するスクリプトを修正する(詳細後述)
    • 今まではCircleCIのAPIを利用していたため
  • GitHub Actionsで利用するsecretを設定する
  • .circleci/config.ymlを削除する

「ビルドがSuccessした直近のcommit」を特定する部分でハマりました。今まではCircleCIのAPIを使ってビルドログ一覧を取得したり条件で絞り込んだり簡単にできていたのですが…。Github ActionsにはそのようなAPIが見当たりませんでした。
Github Actionsの結果を取得するcheck runscheck suites、commitのステータスを取得するstatusesなどのAPIはあるものの、それらからは条件に該当するcommit hashを抽出することはできず、直前のcommitと比較する方法に妥協しました。

いい方法知っている方がいましたらお助けください…!

使ってみた所感

ビルド速度の劣化はありませんでしたので一安心です。

bundle installnpm installしたものをキャッシュする設定はCircleCI(ver2)よりも書きやすく、読みやすいと感じました。

.circleci/config.yml

- restore_cache:
    keys:
      - bundle-cache-{{ checksum "Gemfile.lock" }}
      - bundle-cache-

- save_cache:
    key: bundle-cache-{{ checksum "Gemfile.lock" }}
    paths:
      - vendor/bundle

CircleCIでは「キャッシュする/キャッシュを復元する」記述をそれぞれ書いていました。

.github/workflows/deploy.yml

uses: actions/cache@v1
with:
  path: vendor/bundle
  key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}

Github Actionsでは「何をキャッシュするのか」を記述すれば良いので分かりやすく感じました。「キャッシュがない場合は〇〇する」処理もif: steps.<step_name>.outputs.cache-hit != ‘true’と書けるので直感的でした。

一方で、GitHub Actionsのログを柔軟に取得するAPIがなかったり、結果Viewに「キャッシュをクリアして再ビルドする」ボタンがなかったりと、少し込み入ったことをすると困る場面が多かったです。

まとめ

CircleCIから移行することはできましたし、configファイルも比較的書きやすかったですが、かゆいところに手が届かない印象です。当面は使っていきますが、業務利用はまだ控えておこうと思います。今後に期待します!