先日、 Shinjuku.LT というイベントで話してきたのですが、資料をつくっていなかったため当日話したこと(+α)をここに残しておこうと思います。

話の流れはざっくりいうと、

  • GitHub Services を使って master マージ&自動デプロイしていたが、サービスが終了した
  • 仕方なく手動デプロイしていたが、GitHub Actions で再び自動化できた
  • せっかくなので、GitHub Action をつくって公開してみた

という感じです。

作成した GitHub Action は Marketplace で公開されています 🎉
よかったら使ってみてください。
https://github.com/marketplace/actions/git-pr-release

以降は、 LT で話した流れに沿って内容を書きます。

GitHub Services の利用と終了 🐙

昨年つくりはじめた個人開発のアプリで、「GitHub で master マージすると AWS CodeDeploy で自動デプロイされる」というのを GitHub Services を使ってやっていました。

ググるといくつも記事があがっているので、やっていた人も多かっただろうと思います。
便利だなーとか思いながら過ごしていたのですが、4月になると GitHub Services が終了するという記事が公開されました。

Announcing the deprecation of GitHub Services

終了することを知った後も特に何もせず、いつかなんとかしようとか思ってたら、いつの間にかサービスが終了し、気づいたら手動デプロイが必要な状況になっていました 😇

GitHub Actions の発表 🔈

2018年の GitHub Universe で、 GitHub Actions という新機能が発表されました。
GitHub Actions: みなさんが開発し、GitHubで実行
GitHub Universe 2018

ワークフローの自動化とカスタマイズができるようになるもので、現在(2019/02/26時点)は制限付きパブリックベータ版として公開されています。

本公開前に色々と変更が行われる可能性はありますが、以下のページから登録すれば誰でも利用が可能です。
Register for GitHub Actions Beta

また、ドキュメントは以下のあたりに公開されています。
https://developer.github.com/actions/

自動デプロイの復活 🎉

GitHub Actions で、割と楽に自動デプロイな生活に戻れそうだったので、使ってみることにしました。

ベータ版の利用登録をすると、ヘッダーに Actions タブが追加されます。
ワークフローの定義は GUI またはソースエディタで、わりかし簡単につくれます。
workflow editor

定義されたイベントを起点に、アクションを組み合わせていきます。
awscli を実行できるアクション は既に用意されており、以下のようにワークフローを定義しました。

workflow "Release workflow" {
  on = "release"
  resolves = ["AWS CodeDeploy"]
}

action "AWS CodeDeploy" {
  uses = "actions/aws/cli@efb074ae4510f2d12c7801e4461b65bf5e8317e6"
  args = "deploy create-deployment --application-name {アプリ名} --deployment-group-name {デプロイグループ名} --github-location repository=${GITHUB_REPOSITORY},commitId=${GITHUB_SHA}"
  secrets = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
  env = {
    AWS_DEFAULT_REGION = "ap-northeast-1"
  }
}

workflow ブロックの on で発火イベントを指定します。今回は「master マージ」ではなく「Release タグを Publish」を起点に workflow を実行するようにしました。

Release タグが draft でなく publish したらイベントが発火します。
一度 draft に戻して再度 publish しても発火するので、地味に便利です。

AWS のアクションの方は、 awscli コマンドの引数を args に指定します。
ソースを見るとわかりますが、 Dockerfile の ENTRYPOINT で aws コマンドを実行するようになっています。
secrets の値はGUIで指定します。

CodeDeploy 側は今までも使ってたので、特に変更なくスムーズにデプロイできました 💪

GitHub Action の作成と公開 🚀

今回、 LT 発表するにあたりもう少しネタが欲しいと思っていたので、 GitHub Action をつくることにしました。

自分でリリースフローつくる時にほぼ毎回お世話になっている git-pr-release を GitHub Action で実行できるようにしてみました。

再掲になりますが、以下の GitHub Marketplace のページにあがっています。
https://github.com/marketplace/actions/git-pr-release

GitHub Marketplace - git-pr-release

使い方 📝

ワークフローのサンプルはこんな感じです。

workflow "Create PR to master" {
  resolves = ["git-pr-release"]
  on = "push"
}

action "Filter branch" {
  uses = "actions/bin/filter@24a566c2524e05ebedadef0a285f72dc9b631411"
  args = "branch staging"
}

action "git-pr-release" {
  uses = "bakunyo/git-pr-release-action@master"
  needs = ["Filter branch"]
  secrets = ["GITHUB_TOKEN"]
}

push イベントを起点にワークフローを実行し、Filter branch で「staging ブランチの時」に限定しています。

git-pr-release をセットアップする時に Personal access token を発行した覚えのある方もいると思いますが、このワークフローでは不要です。
GitHub Actions では、GitHub APIをコールするための GITHUB_TOKENあらかじめ用意してくれます
なので、Secrets を指定する所でチェックするだけでOKです。

secrets GITHUB_TOKEN

ステータス「neutral」について 😐

多くのCIサービスと同じように、GitHubのワークフローでも実行コマンドの終了ステータスが 0 なら成功、そうでなければ失敗となり、フローが中断されます。

上記のサンプルでブランチが staging 以外だったらどうなるか?
GitHub Actionではneutral(78)というステータスが用意されました

neutral - branch filter

終了ステータスが neutral だと、 workflow は成功でも失敗でもなく、 Pull Request のマージを妨げません。
自作の GitHub Action をつくる際、適切なタイミングがあれば使ってみると良さそうです。

GitHub Action のつくりかた :man_cook:

公式ドキュメント にわかりやすい説明が書いてあります。
また、既に公開されているアクション も参考になります。

今回つくった Action は こちら です。 README 除くと20行くらいしかないです。 Marketplace に表示される時のアイコンや色を Dockerfile の LABEL で指定できます。

形式を満たしてリポジトリにあげると、 Marketplace に Publish するボタンが表示されます。
publish marketplace

必要事項が整っているかもチェックしてくれるようです。

validate action

公開されている GitHub Actions はまだまだ数が少ない(現在132個)ので、やってみたい人は今が狙い目かもしれないです。

vs CIサービス? ⛈

公開されている GitHub Actions をみると、 Test や Lint を実行するものが多く見られます。
現時点で CI サービスに取って代わるかというと、まだまだそんな感じではないですが、1〜2年後はどうなってるかわからないと思います。

そういう視点でみると、今後の機能としてエラー通知、Services(DBとか)、Cache、Artifacts あたりが追加されそうな気がしました。
今後どうなっていくかはわかりませんが、本公開が楽しみです。