GitHub Actionsに移行してみた
Travis CIからGitHub Actionsに移行してみました。
Table of Contents
GitHub Actionsとは
GitHubが提供するCI/CDの仕組みです。
yaml
ファイル1つであらゆる処理を実行できるのがポイント。
雑に言うと、JenkinsfileのGitHub版みたいなイメージでOKです。
GitHub Actionsそのものの経緯や、料金、仕様、使い方などは以下のサイトが丁寧で分かりやすかったです。
本記事では基本的な部分は割愛しますので、そちらをご覧下さい。
なぜGitHub Actionsを使うのか
以下の理由から、当初は興味がありませんでした。
- HCLよりYAMLが好き
- Travis CIで十分やりたいことができるし、移行が面倒
- CI/CDではなくイベントトリガーアクションがメイン(に思えた)
- ビジュアルエディタは気になりつつも必要性を感じない
しかし、今年になって一気に変わりました。
- YAMLで書ける!
- CI/CDがメイン
- GitHubリポジトリとの強力で安心な連携 (同じGitHubですから)
- Matrix Buildができる
- Dockerを使える
- Dockerを使わなくても色々できそう
- (ネットを見る限り) ビルド待ち時間が無さそう
元々できたこともあると思いますが、この辺が魅力に感じたので使うことにしました。
移行前と移行後
対象リポジトリ
私が開発しているowcliというCLIフレームワークでやりました。
owcliの宣伝
移行前のファイル
Travis CIのYAMLは以下です。
travis.yml
language:
- python
matrix:
include:
- python: "3.6"
dist: xenial
- python: "3.7"
dist: xenial
install:
- pip install pipenv
- make init
script:
- make test-cli
notifications:
slack:
secure: zxxxxx
Travis CIはlanguage: python
を指定することで、PythonやMake, batsなどが入ったVMが提供されていました。
そのため、yamlファイルだけを見るとTravis CIのほうがシンプルだと思います。
移行後のファイル
行数は3倍になりました。
.github/workflows/e2e.yml
name: "e2e tests"
on:
push:
paths:
- '.github/**/*'
- 'owcli/*'
- 'owcli/**/*'
- 'tests/*'
- 'tests/**/*'
- 'Pipfile.lock'
schedule:
- cron: '0 0 * * *'
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python: [ '3.6', '3.7']
name: Python ${{ matrix.python }}
steps:
- name: Checkout a repository
uses: actions/checkout@v1
- name: Install bats
run: sudo npm install -g bats
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip pipfile-requirements
pipfile2req > requirements.txt
pip install -r requirements.txt
- name: Test with bats
run: bats tests/test.bats
- name: Slack notification
uses: homoluctus/slatify@master
if: always()
with:
type: ${{ job.status }}
job_name: ":python:*${{ matrix.python }}* e2e tests"
icon_emoji: "tio2"
url: ${{ secrets.SLACK_WEBHOOK }}
しかし、この比較はフェアではありません。
今回の移行に伴い、ファイルに含まれる情報として以下のような差分があるのです。
- 変更時にジョブを実行するファイルを制限する
- 定期実行する
- makeを使わない
- pipenvを使わない
- pipenvを使うことにより、travis.yamlの方はMatrix buildがちゃんとできていなかった
- Slackのメッセージを細かく制御する
本記事は比較すること自体が目的ではないため、ご了承ください。
YAMLファイル作成中に疑問に思ったことと回答
Actionの一覧はどこにある?
actions
にぶら下がっているリポジトリがそのようです。
定期的に実行する方法は?
on.schedule
にcron形式で設定すればOKでした。
こんな感じですね。
on:
schedule:
- cron: '0 0 * * *'
Status badgeが欲しい
Markdownの場合、以下のように書けばOKです。
[![Actions Status](https://github.com/{ユーザ名}/{リポジトリ名}/workflows/{ワークフロー名}/badge.svg)](https://github.com/{ユーザ名}/{リポジトリ名}/actions)
owcliだと下記のように書きます。
[![Actions Status](https://github.com/tadashi-aikawa/owcli/workflows/e2e%20tests/badge.svg)](https://github.com/tadashi-aikawa/owcli/actions)
参考: Automating your work with Github Actions
Pathsの構文がよく分からない…
owcliでもこう書いていますのでお察しかもしれませんが..
on:
push:
paths:
- '.github/**/*'
- 'owcli/*'
- 'owcli/**/*'
- 'tests/*'
- 'tests/**/*'
- 'Pipfile.lock'
公式では『.gitignore
の書き方でOK』と説明されているようですが、実際はそうなっていないとのこと。
不要なWorkflowの結果を消したい
試行錯誤した過去のWorkflowがずっと残っており、邪魔なので消したいです..。
今のところ消し方が分かりません.. ご存知の方いらっしゃいましたらTwitterにコメントいただけると大変助かります🙇
ビルドスピードとキャッシュ
ビルドキャッシュの対応有無
GitHub Actionsは現時点でビルドキャッシュに対応していないようです。
Dockerでそれまでの結果をキャッシュ化したい場合は、Dockerイメージを作ってアップロードする必要がありそうです。
I want a predefined Docker container to be spun up and get right to work. You can have that too! If you create a Docker image and upload it to Docker Hub or another public registry, you can instruct your Action to use that Docker image specifically using the
docker://
form in theuses
key.
HCLだった時代にはDockerfileの結果はキャッシュとして考慮されていたようですね。
I can confirm that the previous HCL syntax version of Actions does show “Using cache” when building from a Dockerfile as seen here. However, since upgrading to the yml workflows, it stopped caching, as seen in the lack of “Using cache” here.
今後のアップデートに期待したいところですが、構造を考えると難しそうな気がします..。
ビルドスピードを上げるには
インストールやビルドのタスクをできるだけ高速化することが大事だと思いました。
たとえば、owcliのテストで使うBatsは複数のインストール方法があります。
- npm
- ソースからビルド
- Docker
実際に比較していませんが、この中で最速なのは恐らくnpm
です。
npm install -g bats
は12秒で終わりました。
GitHub Actionsが利用するイメージはかなり全部盛りです。
Ubuntu 18.04 LTSの場合は以下に記載されたpackageが入っています。
ビルドキャッシュが使えない以上、イメージに含まれているpackageを最大限に利用してジョブを作成していきましょう👍
並列処理/最大20並列の恩恵
たとえ他のCIサービスより1つのジョブを実行する時間がかかっても、最大20並列できるというのは圧倒的メリットです😄
Matrix Buildをしているプロダクトなら、総合的にはGitHub Actionsの方が早くジョブの実行が完了するのではないでしょうか。
Slack通知
現状、GitHub ActionsはSlack通知の仕組みを提供していません。
Slack通知は必須のため、Actionをいくつか調べたところ以下を利用させていただくことにしました。
Slatifyに決めた理由
一番の決め手はTwitterでお声がけいただいたことですね😃
もちろん、それだけではありません。
- Ownerの技術的背景に親近感を感じた (TS/Python/Goなど)
- Ownerが日本人
- 機能が必要十分で直感的だった
- 要望をFBしたらスピーディーに対応いただけた
SlackのActionが今後沢山出てきそうですが、個人的に応援しております👍
設定方法
owcliでは以下の様な設定にしています。
- name: Slack notification
uses: homoluctus/slatify@master
if: always()
with:
type: ${{ job.status }}
job_name: ":python:*${{ matrix.python }}* e2e tests"
icon_emoji: "tio2"
url: ${{ secrets.SLACK_WEBHOOK }}
事前準備として、リポジトリの秘密情報SLACK_WEBHOOK
にSlack Incoming Webhooks URLを設定する必要があります。
通知の結果はこのように表示されます。
今後、失敗したときはメンションを飛ばすようにするかもしれません。 (job_name
に入れればいけそう)
総括
Travis CIからGitHub Actionsに移行したとき、気になったことと知見をまとめてみました。
今のところ、イベント発生からジョブ実行までの間にほぼラグはありません。
また、ジョブの実行速度自体も非常に高速です。
現状は招待制ベータであるため、利用ユーザはそこまで多くないと思います。
実際、私も申し込みをしてから利用開始までは1ヶ月くらいかかりました。
正式にサービスインした後もこのスピード感が維持されるかは要注目です。
ただ、スピード感が落ちたとしてもGitHub Actionsは間違い無く有用です。 そのため、owcli以外のプロジェクトもGitHub Actionsに随時移行していきます。