ProbotでGitHubのBotを作成してGlitchにデプロイしてみる
GitHubを使う上で、チームによってローカルルールがある場合があると思います。これをみんなで守るためには、例えば啓蒙活動やレビューで頑張ることも一つの方法ですが、本質的には「そもそもルールを破れない状況を作る」ことが一番大切であるように思えます。
GitHubではBotを作成することができるので、ある程度GitHubの使い方に関するローカルルールをBotによって強制的に守らせることが可能です。
本記事では、「Issueを閉じる際にはラベルとマイルストーンが設定されていなければいけない」といったルールを守らせるためのBotをProbotで作成し、Glitchにデプロイしてみました。
本記事で行うこと
- ProbotによるGitHubのBot作成
- Issueをクローズした際にマイルストーンもしくはラベルが未指定の場合、Issueに注意コメントをつけた上で再度オープンする
- ローカルでProbotによるアプリケーションを起動してテスト
- Glitchにデプロイ
前提条件
- ローカルでNode.jsが動作すること
- 本記事ではv8.11.2で動作確認をしました
各要素の簡単な説明
Probot
ProbotはGitHub Appsを作成するためのフレームワークです。
主な機能として、
- GitHubのWebHookから送信された各イベントに対する処理
- GitHubのAPI実行
を簡潔に記載することができます。
Glitch
Glitchが本質的になんなのかについてはまだいまいち掴めていませんが、本記事ではGitHubと連携可能なエディタ兼Node.jsのPaaSとして使用しています。
ざっと見た感じではGitHubとPaaSの中間のようなサービスに見えますが、詳しくは公式をご覧ください。
参考:Glitch - The community where you'll build the app of your dreams
やってみる
Probot
プロジェクトの作成
以下のコマンドを実行し、Botの準備のための質問にいくつか答えるとProbotによるBotのためのテンプレートが作成されます。
test-inabaの部分には作成したいBotの名前を指定します。
1 | $ npx create-probot-app test-inaba |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | npx: 226個のパッケージを10.752秒でインストールしました。Let's create a Probot app!? **App name:** test-inaba? **Description of app:** A Probot app? **Author's full name:** inabajunmr? **Author's email address:** inabajun.for.regi@gmail.com? **Homepage:**? **GitHub user or org name:** inabajunmr? **Repository name:** test-inaba〜略〜added 993 packages in 26.38sDone! Enjoy building your Probot app! |
完了すると指定した名前のディレクトリ配下にテンプレートが作成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $ ls -la test-inabatotal 672drwxr-xr-x 15 inabajunmr staff 480 5 28 02:44 .drwxr-xr-x 31 inabajunmr staff 992 5 28 02:44 ..-rw-r--r-- 1 inabajunmr staff 236 5 28 02:44 .env.example-rw-r--r-- 1 inabajunmr staff 56 5 28 02:44 .gitignore-rw-r--r-- 1 inabajunmr staff 81 5 28 02:44 .travis.yml-rw-r--r-- 1 inabajunmr staff 3224 5 28 02:44 CODE_OF_CONDUCT.md-rw-r--r-- 1 inabajunmr staff 1790 5 28 02:44 CONTRIBUTING.md-rw-r--r-- 1 inabajunmr staff 772 5 28 02:44 LICENSE-rw-r--r-- 1 inabajunmr staff 170 5 28 02:44 README.mddrwxr-xr-x 2 inabajunmr staff 64 5 28 02:44 etc-rw-r--r-- 1 inabajunmr staff 282 5 28 02:44 index.jsdrwxr-xr-x 674 inabajunmr staff 21568 5 28 02:44 node_modules-rw-r--r-- 1 inabajunmr staff 304624 5 28 02:44 package-lock.json-rw-r--r-- 1 inabajunmr staff 722 5 28 02:44 package.jsondrwxr-xr-x 3 inabajunmr staff 96 5 28 02:44 test |
Botの設定
テストのためにsmee.ioを利用します。smee.ioで割り当てられたURLをGitHubのWebHookに指定することで、smee.io経由でローカルで起動したアプリケーションでリクエストを受け取ることができます。
Start a new channelをクリックするとWebhook Proxy URLが割り当てられるので、これをメモしておきます。
Register new GitHub Appから新規登録をします。
Webhook URLにsmee.ioで取得したWebhook Proxy URLを指定し、Webhook
secretにdevelopmentを指定します。
PermissionsにはIssuesのRead&Writeを、Subscribe to eventsにはIssuesを指定します。
前者はBotからGitHubへのアクセス権限で、後者はWebHookを発火させるEventの指定となります。 作成後のページにIDが表示されるので、こちらもメモしておきます。
最後に、Generate a private keyから秘密鍵を生成し、プロジェクトのディレクトリ直下に配置します。
作成したらnpx create-probot-appで作成したディレクトリの.env.exampleを.envにコピーし、編集します。
APP_IDにGitHubで取得したIDを、WEBHOOK_PROXY_URLにはsmee.ioで取得したURLを指定します。
1 2 3 4 5 6 7 | $ cp .env.example .env$ vi .env$ cat .envAPP_ID=12729WEBHOOK_SECRET=developmentLOG_LEVEL=debugWEBHOOK_PROXY_URL=https://smee.io/XXXXXXXX |
Botの動作を編集します。index.jsを以下に修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | module.exports = (robot) => { // WebHookによって発火するイベントを定義(IssueのClose時に動作) robot.on('issues.closed', async context => { const exist_label = context.payload.issue.labels.length != 0; const exist_milestone = context.payload.issue.milestone != ''; if (exist_label && exist_milestone) { // ラベルとマイルストーンが設定されていれば何もしない return; } const comment = context.issue({body: 'You must add milestone and label!'}) // Issueにコメントを追加 context.github.issues.createComment(comment) // Issueをオープンする const open = context.issue({state: 'open'}) context.github.issues.edit(open) })} |
コメントの通りですが、構造的には「GitHubに対して何をすると、何が起きるか」です。 上記ではIssueが閉じたタイミングでスクリプトが実行し、ラベルとマイルストーンが設定されていなければIssueに「You must add milestone and label!」とコメントし、IssueをOpenします。
「何をすると」の部分、つまりWebHookの定義についてはこちらを参照してください。 例えばIssueそのものに対するイベントであればこちらが、Issueのコメントに対するイベントであればこちらとなります。
また、「何が起きるか」については単純にスクリプトを書いていけばいいのですが、GitHubのAPIについては@octokit/restによる操作が可能です。
詳細な定義はこちらを参照してください。
context.githubがoctokitのインスタンスとなります。
GitHubのリポジトリに作成したBotをインストールする
https://github.com/settings/apps/${xxxxx}/installations から作成したBotをインストールできます。${xxxxx}には作成したアプリ名を指定してください。
Installをクリックし、Botの適用範囲を指定します。
インストールできました。
起動する
以下でローカルにBotを起動できます。
1 | $ npm run dev |
起動した状態で、指定したリポジトリのIssueをラベル未指定のまま閉じてみます。
BotによるIssueへのコメントとIssueのオープンが確認できました。
Glitchにデプロイする
ProbotのチュートリアルではGlitch、Heroku、Nowへのデプロイがそれぞれ紹介されていますが、ここではGlitchへデプロイしてみます。
BotをGitHubのリポジトリに追加する
Glitchでデプロイする際にGitHub経由でアプリケーションを送るため、作成したBotをGitHubのリポジトリに追加します。
1 2 3 4 | $ git remote add inabajunmr https://github.com/inabajunmr/test-inaba$ git add .$ git commit -m "initial"$ git push --set-upstream inabajunmr master |
Glitchの設定
こちらからGlitchのプロジェクトを作成します。GitHubアカウントでのサインインが可能です。
Advanced OptionsからGitHubへのアクセス権限を追加し、Import from GitHubでBotのリポジトリをインポートします。
リポジトリを指定します。
インポートできました。
プロジェクトの名前を変更します。
.envファイルを編集します。
1 2 3 4 | APP_ID=12729WEBHOOK_SECRET=XXXXPRIVATE_KEY_PATH=.data/private-key.pemNODE_ENV=production |
APP_IDはローカルで指定した.envの内容と同様です。
WEBHOOK_SECRETは以下のコマンドで生成した値を指定しました。
1 | $ openssl rand -base64 32 |
.data/private-key.pemを作成します。ファイルに先ほどダウンロードした秘密鍵をコピペします。
Showをクリックすると、デプロイされたアプリケーションにアクセスできます。
GitHub Appsの再設定
以下のURLからBotの設定画面を再度開きます。${xxxxx}には作成したアプリ名を指定してください。 https://github.com/settings/apps/${xxxxx}
先ほどdevelopmentと指定したWebhook secretに、新しく生成した値を指定し直します。
また、Webhook URLにGlitchのURLを指定します。今回の場合、https://test-inaba.glitch.meとなります。ShowからアクセスできるアプリケーションのURLから、/probotを無くしたものがWebhook
URLとなります。
設定が完了したので、再度GitHubにてテストしたところ正常に動作することが確認できました。
まとめ
ProbotはGitHub Appsを作成するためのフレームワークです。
主な機能として、
- GitHubのWebHookから送信された各イベントに対する処理
- GitHubのAPI実行
を簡潔に記載することができます。
ProbotでGitHubのBotを作成し、Glitchでデプロイしてみました。 Probotの設定および実装は非常にシンプルにできており、Botの実装が簡単に行えそうです。
私からは以上です。