Node.js
GitHub
開発環境
自動化
Probot
DMM.comDay 1

GitHub上の作業を自動化して幸せになろう 〜ProbotでGitHub Appsを作る〜

DMM.com Advent Calendar 2018 1日目の記事です。

こんにちは。DMM.comのサービス全体で利用される認証基盤の開発・運用を担当している@_kentaro_mです。

みなさん、GitHubは使っていますか。DMMではGitHub Enterpriseが導入されており、システム開発する上で無くてはならない存在となっています。

DMM.comのGitHub EnterpriseとCircleCI Enterpriseの活用例 | GitHub Resources

本日はGitHub上で発生する作業を自動化するために、GitHubと連携するアプリケーション「GitHub Apps」とそれを作るためのフレームワークである「Probot」を試してみたので紹介したいと思います。


その作業、自動化できますよ

GitHubを使っていると、あの作業自動化できるのではという場面に遭遇することがあります。


  • Pull Requestをマージしたタイミングで自動でブランチを削除して欲しい

  • Pull Requestが作成されたタイミングで特定のレビュアーを追加して欲しい

  • Pull RequestのタイトルにWIPが含まれているときにマージできないようにして欲しい

  • 一定期間動きのないIssueをクローズしたい

このような作業を自動化するために、GitHub Appsという仕組みがGitHubより提供されています。リポジトリにアプリケーションをインストールすることで、例に挙げた作業を自動で行ってくれます。

GitHub Appsは誰でも公開することが可能で、以下のように既に多くのアプリケーションが公開されています。「Add to GitHub」ボタンを押すと、すぐに利用可能です。



  • Delete merged branch


    • Pull Requestをマージしたタイミングで自動でブランチを削除する




  • Auto Assign


    • Pull Requestを作成したタイミングで特定のレビュアーを追加する




  • Work In Progress


    • Pull RequestのタイトルにWIPが含まれているときにマージできないようにする




  • Stale


    • 一定時間動きのないIssueを自動でクローズする



他にも様々な作業を自動化するGitHub Appsが公開されています。

Featured Apps | Probot


作業の自動化を支える仕組み

GitHub上の作業自動化を実現する仕組み「GitHub Apps」とそれを作るためのフレームワーク「Probot」について詳しく見ていきます。


GitHub Apps

GitHub AppsはGitHubと連携するアプリケーションの形式です。OrganizationアカウントまたはUserアカウントに直接インストールして使用します。

基本的にはリポジトリのイベント受信 (Webhook受信) をトリガーに動作し、リポジトリを操作 (API実行) する動作のアプリケーションが多いです。

github_apps.png

例えば、Pull Requestのマージでブランチを自動削除するDelete merged branchの場合は、Pull Requestをマージしたイベントをトリガーに動作し、ブランチを削除するAPIを呼び出して、作業自動化を実現しています。

GitHub Appsの特徴としては、インストールしたアカウント配下のリポジトリごとにアクセス制御が可能な点です。リポジトリのイベント受信とリポジトリ操作の権限を与えるかをそれぞれのリポジトリで設定し、アプリケーション動作の有効・無効を制御しています。


Probot

ProbotはGitHub Appsを作るためのフレームワークです。TypeScriptまたはJavaScriptで開発することが可能で、リポジトリのWebhook受信やGitHub API実行を簡単に利用できる仕組みを提供しています。


GitHub Appsを作る

ProbotでGitHub Appsを実際に作ってみたいと思います。今回はサンプルとして、Pull Requestがオープンしたタイミングで「レビュー可能」というラベルを追加するアプリケーションを作りたいと思います。

Screen_Shot_2018-11-29_at_1_52_27.png

以下の手順で作っていきます。Developing an app | Probotに記載されているとおりです。


  1. create-probot-appでプロジェクトテンプレートを作る

  2. app.ymlを変更し、アクセス権限を設定する

  3. GitHubにアプリケーションを登録する

  4. Pull Requestへのラベル追加処理を実装する

  5. アプリケーションの動作確認を行う


1. create-probot-appでプロジェクトテンプレートを作る

yarnコマンド (or npxコマンド)でプロジェクトテンプレートを作成することができます。

2018年11月27日時点でプロジェクトテンプレートは4種類、Issueのコメント追加(basic-js/basic-ts)、アプリケーションのデプロイ(deploy-js)、リポジトリのGit操作(git-data-js)、Checks APIとの連携(checks-js)が用意されています。

Issueのコメント追加のみTypeScriptに対応していました。

probot/create-probot-app: 🤖📦 Create a new probot app

❯ yarn create probot-app pr-add-label

yarn create v1.9.4
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Installed "create-probot-app@3.0.2" with binaries:
- create-probot-app

Let's create a Probot app!
Hit enter to accept the suggestion.

? App name: pr-add-label
? Description of app: A Probot app
? Author's full name: Kentaro Matsushita
? Author's email address:
? Homepage:
? GitHub user or org name: kentaro-m
? Repository name: pr-add-label
? Which template would you like to use? basic-ts

yarn buildコマンドでTypeScriptのビルド、yarn devコマンドでローカル実行が可能です。

❯ cd pr-add-label

❯ yarn build && yarn dev
Welcome to Probot! Go to http://localhost:3000 to get started.

ローカルホストにアクセスすると、アプリケーション起動が確認できます。

Screen Shot 2018-11-27 at 1.54.42.png

Ctrl + Cでアプリケーションを停止します。


2. app.ymlを変更し、アクセス権限を設定する

アプリケーションの動作に必要な権限を付与します (app.ymlに定義せずにGitHub Appsの管理画面から設定することも可能です)。

付与できるアクセス権限は以下より詳細を確認ください。


app.yml

default_events:

# プルリクエストイベントを受信許可
# (プルリクエストが作成されたイベントを拾うため)
- pull_request

default_permissions:
# メタ情報のread権限付与
metadata: read
# プルリクエストのwite権限付与
# (プルリクエストにラベルを追加するため)
pull_requests: write



3. GitHubにアプリケーションを登録する

GitHubでアプリケーションを動作させるために登録作業が必要です。登録方法は2種類あり、その違いはGitHub Apps設定画面の必要項目の入力を自動入力するか、手入力するかの違いがあります。

今回は自動登録で説明します。手動で登録したい方は下記リンクを参照ください。

Manually Configuring a GitHub App | Probot

再度アプリケーションを起動し、ローカルホストにアクセスします。

❯ yarn build && yarn dev

Welcome to Probot! Go to http://localhost:3000 to get started.

Register GitHub Appをクリックします。

Screen_Shot_2018-11-29_at_0_21_16.png

アプリケーションの名前を入力します。変更がなければ、Create GitHub Appをクリックします。

Screen Shot 2018-11-29 at 0.25.32.png

アプリケーションをインストールするアカウントを選択します。

Screen_Shot_2018-11-29_at_0_26_50.png

アプリケーションの動作を許可するリポジトリの選択と付与したアクセス権限の確認を行います。ここで表示される権限はapp.ymlで定義したものです。問題なければ、Installをクリックします。

Screen_Shot_2018-11-29_at_0_30_43.png

アプリケーションのインストール後、ローカル開発環境ではアプリケーションの動作に必要な情報が記載された.envファイルが生成されます。

WEBHOOK_PROXY_URL=<Webhookを受信するエンドポイント>

APP_ID=<アプリのID>
PRIVATE_KEY=<秘密鍵>
WEBHOOK_SECRET=<Webhookをセキュアに扱うための認証トークン>


4. Pull Requestへのラベル追加処理を実装する

ラベル追加処理はapp.onでPull Request作成のWebhookイベント受信をトリガーに、context.github(@octokit/rest: Node.js製GitHub APIクライアントのインスタンス)でラベル追加APIを実行して実現しています。

Webhook受信及びGitHub APIの呼び出しに関しての詳細は以下公式ドキュメントをご覧ください。


src/index.ts

import { Application } from 'probot' // eslint-disable-line no-unused-vars

export = (app: Application) => {
// Pull Requestが作成されたタイミングで呼び出されます
app.on('pull_request.opened', async (context) => {

// ラベル追加APIを呼び出す際のリクエストパラメータ生成
// Returns: {owner: 'username', repo: 'reponame', number: 123, labels: ['レビュー可能']}
const params = context.issue({
labels: ['レビュー可能']
})

// 作成されたPull Requestにラベル追加
await context.github.issues.addLabels(params)
})
}



5. ローカルでアプリケーションの動作確認を行う

smee.ioというWebサービスを利用し、インターネット上に公開したエンドポイントでWebhookイベントの受信を行い、ポートフォワーディングを利用してローカルホストで受け取ることが可能です。この仕組みを利用することで、効率よく開発できます。

アプリケーションのビルドと起動を行います。

❯ yarn build && yarn start

さきほどアプリケーションをインストールしたリポジトリでプルリクエストを作成します。

Screen Shot 2018-11-29 at 1.51.26.png

ラベル追加に成功しました。

Screen_Shot_2018-11-29_at_1_52_27.png

うまく動作しない場合はコンソールに出力されているログを確認しましょう。

Screen_Shot_2018-11-29_at_1_57_22.png

また、直近のWebhookイベントは記録されているので、GitHub AppsのAdvanced設定画面から再送することができます。この機能を使用して、効率よくデバッグしましょう。

Screen_Shot_2018-11-29_at_2_13_06.png


GitHub Appsを公開する

ローカルでアプリケーションの動作確認が済んだら、アプリケーションを公開するために無料で利用できるクラウドプロバイダーにデプロイを行います。


無料で利用できるクラウドプロバイダーにデプロイしよう

公式ではHeroku、Now、Glitchにデプロイする方法が紹介されています。

Deployment | Probot

今回はブラウザ操作のみでデプロイできるGlicthを使って、デプロイを行います。事前に作成したアプリケーションコードをGitHubリポジトリにPushしておいてください。

さきほど作成したアプリケーションのGitHubリポジトリ

kentaro-m/pr-add-label

以下のリンクをクリックすると、Glitchで新しいプロジェクトが作成されます。

Glitchで新しいプロジェクトを作成する

次にGitHubからコードをインポートします。左上のプロジェクト名をクリックし、Advanced Options > Import from GitHubを選択し、インポートしたいGitHubリポジトリを入力して、OKをクリックします。

Screen_Shot_2018-11-30_at_0_32_18.png

少し待つと、GitHubからコードが読み込まれます。

Screen Shot 2018-11-30 at 0.38.53.png

次にアプリケーション動作に必要な環境情報を.envファイルに追加します。

APP_ID=<ローカル開発環境の.envファイルの値をコピー>

WEBHOOK_SECRET=<ローカル開発環境の.envファイルの値をコピー>
PRIVATE_KEY=<ローカル開発環境の.envファイルの値をコピー>
NODE_ENV=production

設定が完了したら、動作確認を行います。上部のShowボタンを押すと、別タブでアプリケーションの詳細ページが表示されます。

Screen_Shot_2018-11-30_at_1_29_17.png

アドレスバーに表示されたURLの/probotを除いた値がWebhookイベントを受信するエンドポイントになります。

Screen_Shot_2018-11-30_at_1_34_36.png

GitHubのDeveloper Settings > GitHub Apps > 作成したGitHub Appの設定画面と進み、Webhook URLの値を先ほど取得したURLで置き換えます。また、Webhook secretの値もローカル開発環境の.envファイルの値をコピーして貼り付けます。Save changesをクリックして、設定完了です。

Screen_Shot_2018-11-30_at_1_45_43.png

最後にアプリケーションをインストールしたリポジトリでPull Requestを作成して動作確認を行います。ラベルが追加されていることが確認できました。

Screen Shot 2018-11-30 at 2.36.14.png

GlitchではStatusボタンを押すと、ログの確認を行うことができます。先ほど紹介したWebhookイベントの再送機能と組み合わせると、デバッグが容易になると思います。

Screen_Shot_2018-11-30_at_2_37_12.png


開発したアプリケーションを他のユーザーにも使ってもらおう

アプリケーションを他のユーザーに使ってもらうためには公開する必要があります。

GitHubのDeveloper Settings > GitHub Apps > 作成したGitHub Appの設定画面 > Advanced SettingsのMake publicボタンを押すと、公開されます。

Screen_Shot_2018-11-30_at_2_53_49.png

アプリケーションごとに発行されるURL(https://github.com/apps/<アプリケーション名>)を他のユーザに共有してください。

Screen Shot 2018-11-30 at 2.51.56.png


公式サイトに掲載してもらおう

公式サイトにはFeatured Appsというページがあり、数多くのGitHub Appsが紹介されています。

以下のリポジトリにPull Requestを出すことで、自分が開発したGitHub Appsを掲載してもらうことが可能です。多くの開発者が利用できる便利なGitHub Appsができたら、Pull Requestを送ってみてください。

probot/probot.github.io: This is the home of probot documentation, apps, how-to guides and more.

Screen Shot 2018-11-30 at 2.57.57.png

実は私自身もGitHub Appsを作って公開しています。Pull Requestが作成されたタイミングで任意のユーザーをレビュアーとして追加する「Auto Assign」というアプリケーションを公開しています。もし、興味があればお試しください。

kentaro-m/auto-assign: 🤖 A Probot app that adds reviewers to pull requests when pull requests are opened.

Screen Shot 2018-12-01 at 11.18.08.png


GitHub Appsを運用する

GitHub Appsをしばらく運用してみての知見を共有したいと思います。


アクセス権限の設定変更には注意しよう

アプリケーションの公開後のアクセス権限の変更はユーザーの許可が必要です。インストールしているユーザーにメールが送信されて、専用ページから権限変更を許可してもらう流れとなります。

Screen Shot 2018-12-01 at 11.27.18.png

各ユーザーが権限変更許可をしたかについては知る方法がないので、権限の変更前後で異なる権限を持ったアプリケーションが存在することになり、動作不良の原因調査が難しくなります。

パブリックリポジトリとプライベートリポジトリで十分な動作確認を行った上でアプリケーションを公開することをおすすめします。


Sentryでエラーをトラッキングしよう

アプリケーションを運用すると、様々なエラーが発生します。エラーを早期発見して、原因調査及び修正を行うためにSentryというエラートラッキングツールを使用しています。

1ヶ月あたり1万件までエラーを無料で収集することができます。Probot公式のドキュメントでも紹介されているので、本格的に運用する際は導入するのが良いと思います。

Error tracking | Probot

Screen Shot 2018-12-01 at 11.49.23.png


外形監視サービスでサーバーのスリープを防止しよう

アプリケーションをホスティングしているクラウドプロバイダーは一定期間のアクセスがないと、サーバーがスリーブします。これを防ぐために外形監視サービスを利用して、定期的にアクセスしています。

Website Monitoring & Downtime Updates | StatusCake

Screen_Shot_2018-12-01_at_11_39_45.png


今後試したいこと


GitHub Actionsとの連携を試したい

先日のGitHub UniverseでGitHub Actionsというサービスが発表されました。これはアプリケーションのビルドやデプロイ、テストなど開発者のワークフロー実行をGitHub上で自動化できるものです。

現在はベータ版提供となっており、一部ユーザのみに公開されています(私もベータ版テスターに申し込んで、使える日を首を長くして待ってます)。GitHub Actionsで定義するワークフロー上でProbotの機能を利用できるそうなので試したいです。

GitHub Actions: みなさんが開発し、GitHubで実行 | The GitHub Blog


GitHub Enterpriseで動作を確認したい

.envファイルに環境変数を追加することで、GitHub Enterprise上でも動作できます。今回は時間の関係でここまでできませんでしたが、社内でもGitHub Appsを活用するために検証していきたいです。


.env

GHE_HOST=fake.github-enterprise.com



さいごに

Probotで実際にGitHub Appsを作って公開するところまで試しました。ドキュメントや開発環境が充実しているため、非常に簡単にアプリケーションを作ることができました。

冒頭でも紹介した通り、他の開発者が作ったGitHub Appsを利用することもできるので、どんどん自動化して幸せになりましょう。

明日は @i35_267 さんの記事になります。引き続きDMM.com Advent Calendar 2018をお楽しみください。