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が公開されています。
作業の自動化を支える仕組み
GitHub上の作業自動化を実現する仕組み「GitHub Apps」とそれを作るためのフレームワーク「Probot」について詳しく見ていきます。
GitHub Apps
GitHub AppsはGitHubと連携するアプリケーションの形式です。OrganizationアカウントまたはUserアカウントに直接インストールして使用します。
基本的にはリポジトリのイベント受信 (Webhook受信) をトリガーに動作し、リポジトリを操作 (API実行) する動作のアプリケーションが多いです。
例えば、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がオープンしたタイミングで「レビュー可能」というラベルを追加するアプリケーションを作りたいと思います。
以下の手順で作っていきます。Developing an app | Probotに記載されているとおりです。
- create-probot-appでプロジェクトテンプレートを作る
- app.ymlを変更し、アクセス権限を設定する
- GitHubにアプリケーションを登録する
- Pull Requestへのラベル追加処理を実装する
- アプリケーションの動作確認を行う
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.
ローカルホストにアクセスすると、アプリケーション起動が確認できます。
Ctrl
+ C
でアプリケーションを停止します。
2. app.ymlを変更し、アクセス権限を設定する
アプリケーションの動作に必要な権限を付与します (app.yml
に定義せずにGitHub Appsの管理画面から設定することも可能です)。
付与できるアクセス権限は以下より詳細を確認ください。
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.
アプリケーションの名前を入力します。変更がなければ、Create GitHub Appをクリックします。
アプリケーションの動作を許可するリポジトリの選択と付与したアクセス権限の確認を行います。ここで表示される権限はapp.yml
で定義したものです。問題なければ、Installをクリックします。
アプリケーションのインストール後、ローカル開発環境ではアプリケーションの動作に必要な情報が記載された.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の呼び出しに関しての詳細は以下公式ドキュメントをご覧ください。
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
さきほどアプリケーションをインストールしたリポジトリでプルリクエストを作成します。
ラベル追加に成功しました。
うまく動作しない場合はコンソールに出力されているログを確認しましょう。
また、直近のWebhookイベントは記録されているので、GitHub AppsのAdvanced設定画面から再送することができます。この機能を使用して、効率よくデバッグしましょう。
GitHub Appsを公開する
ローカルでアプリケーションの動作確認が済んだら、アプリケーションを公開するために無料で利用できるクラウドプロバイダーにデプロイを行います。
無料で利用できるクラウドプロバイダーにデプロイしよう
公式ではHeroku、Now、Glitchにデプロイする方法が紹介されています。
今回はブラウザ操作のみでデプロイできるGlicthを使って、デプロイを行います。事前に作成したアプリケーションコードをGitHubリポジトリにPushしておいてください。
さきほど作成したアプリケーションのGitHubリポジトリ
kentaro-m/pr-add-label
以下のリンクをクリックすると、Glitchで新しいプロジェクトが作成されます。
次にGitHubからコードをインポートします。左上のプロジェクト名をクリックし、Advanced Options > Import from GitHubを選択し、インポートしたいGitHubリポジトリを入力して、OKをクリックします。
少し待つと、GitHubからコードが読み込まれます。
次にアプリケーション動作に必要な環境情報を.env
ファイルに追加します。
APP_ID=<ローカル開発環境の.envファイルの値をコピー>
WEBHOOK_SECRET=<ローカル開発環境の.envファイルの値をコピー>
PRIVATE_KEY=<ローカル開発環境の.envファイルの値をコピー>
NODE_ENV=production
設定が完了したら、動作確認を行います。上部のShowボタンを押すと、別タブでアプリケーションの詳細ページが表示されます。
アドレスバーに表示されたURLの/probot
を除いた値がWebhookイベントを受信するエンドポイントになります。
GitHubのDeveloper Settings > GitHub Apps > 作成したGitHub Appの設定画面と進み、Webhook URLの値を先ほど取得したURLで置き換えます。また、Webhook secretの値もローカル開発環境の.envファイルの値をコピーして貼り付けます。Save changesをクリックして、設定完了です。
最後にアプリケーションをインストールしたリポジトリでPull Requestを作成して動作確認を行います。ラベルが追加されていることが確認できました。
GlitchではStatusボタンを押すと、ログの確認を行うことができます。先ほど紹介したWebhookイベントの再送機能と組み合わせると、デバッグが容易になると思います。
開発したアプリケーションを他のユーザーにも使ってもらおう
アプリケーションを他のユーザーに使ってもらうためには公開する必要があります。
GitHubのDeveloper Settings > GitHub Apps > 作成したGitHub Appの設定画面 > Advanced SettingsのMake publicボタンを押すと、公開されます。
アプリケーションごとに発行されるURL(https://github.com/apps/<アプリケーション名>
)を他のユーザに共有してください。
公式サイトに掲載してもらおう
公式サイトには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.
実は私自身もGitHub Appsを作って公開しています。Pull Requestが作成されたタイミングで任意のユーザーをレビュアーとして追加する「Auto Assign」というアプリケーションを公開しています。もし、興味があればお試しください。
GitHub Appsを運用する
GitHub Appsをしばらく運用してみての知見を共有したいと思います。
アクセス権限の設定変更には注意しよう
アプリケーションの公開後のアクセス権限の変更はユーザーの許可が必要です。インストールしているユーザーにメールが送信されて、専用ページから権限変更を許可してもらう流れとなります。
各ユーザーが権限変更許可をしたかについては知る方法がないので、権限の変更前後で異なる権限を持ったアプリケーションが存在することになり、動作不良の原因調査が難しくなります。
パブリックリポジトリとプライベートリポジトリで十分な動作確認を行った上でアプリケーションを公開することをおすすめします。
Sentryでエラーをトラッキングしよう
アプリケーションを運用すると、様々なエラーが発生します。エラーを早期発見して、原因調査及び修正を行うためにSentryというエラートラッキングツールを使用しています。
1ヶ月あたり1万件までエラーを無料で収集することができます。Probot公式のドキュメントでも紹介されているので、本格的に運用する際は導入するのが良いと思います。
外形監視サービスでサーバーのスリープを防止しよう
アプリケーションをホスティングしているクラウドプロバイダーは一定期間のアクセスがないと、サーバーがスリーブします。これを防ぐために外形監視サービスを利用して、定期的にアクセスしています。
Website Monitoring & Downtime Updates | StatusCake
今後試したいこと
GitHub Actionsとの連携を試したい
先日のGitHub UniverseでGitHub Actionsというサービスが発表されました。これはアプリケーションのビルドやデプロイ、テストなど開発者のワークフロー実行をGitHub上で自動化できるものです。
現在はベータ版提供となっており、一部ユーザのみに公開されています(私もベータ版テスターに申し込んで、使える日を首を長くして待ってます)。GitHub Actionsで定義するワークフロー上でProbotの機能を利用できるそうなので試したいです。
GitHub Actions: みなさんが開発し、GitHubで実行 | The GitHub Blog
GitHub Enterpriseで動作を確認したい
.env
ファイルに環境変数を追加することで、GitHub Enterprise上でも動作できます。今回は時間の関係でここまでできませんでしたが、社内でもGitHub Appsを活用するために検証していきたいです。
GHE_HOST=fake.github-enterprise.com
さいごに
Probotで実際にGitHub Appsを作って公開するところまで試しました。ドキュメントや開発環境が充実しているため、非常に簡単にアプリケーションを作ることができました。
冒頭でも紹介した通り、他の開発者が作ったGitHub Appsを利用することもできるので、どんどん自動化して幸せになりましょう。
明日は @i35_267 さんの記事になります。引き続きDMM.com Advent Calendar 2018をお楽しみください。