最近、チームのプロジェクト管理ツールをJIRAからZenHubに変更しました。ZenHubはスクラム開発と親和性が高く、導入後のチームメンバーからの評判も上々です。
ZenHubはそのまま利用しても便利なツールではありますが、WebhookやAPIなどの機能が提供されており、これらを使用することでそれぞれの現場に存在するワークフローに対応した仕組みを作ることができます。
私自身も将来的に上図のように、特定のレーンに移動したときにIssueの入力項目が足りていない場合にコメントを付ける仕組みを作りたいと考えています。
本記事ではその初歩として、ローカルでZenHubのWebhookを受け取って表示するところまでを行いたいと思います。
完成形の共有
Node.jsで簡単なWebサーバーを作成して、Webhookを受け取ります。今回はngrokというサービスを利用し、ローカルの開発環境にWebhookリクエストが送信されるようにしています。
実際にWebhookの受け取りに成功した場合は下記のようになります。
$ node index.js
Listening on 6000
{ type: 'issue_transfer',
github_url: 'https://github.com/kentaro-m/auto-assign/issues/31',
organization: 'kentaro-m',
repo: 'auto-assign',
user_name: 'kentaro-m',
issue_number: '31',
issue_title: 'Error: Resource not accessible by integration',
to_pipeline_name: 'Review/QA',
from_pipeline_name: 'In Progress' }
ZenHubのサポートページによると、受け取れるWebhookのイベントは以下の4種類となっています。
-
Issue transfer
レーンの移動 -
Estimate Set
見積もりの設定 -
Estimate Cleared
見積もりの消去 -
Issue Reprioritized
優先度の変更 (レーン内での上下移動)
詳細は下記のサポートページをご覧ください。
ZenHubIO/API: Learn how to use ZenHub's API.
ZenHubの登録
GitHubアカウントで登録可能です。今回はパブリックリポジトリ向けに用意されている無料プランを使用します。
もし、ZenHubの準備ができていない場合は、以下の手順で登録及びログインを行ってください。
ZenHubのWebサイトの右上の「Login」ボタンを押下します。その後に「Sign in with GitHub」を押下し、連携を許可すると、登録完了です。
適当なGitHubリポジトリを選択して、ボードを作成しましょう。
新規プロジェクトの作成
ZenHubのボードの作成が完了したら、Webサーバーの準備を行います。
適用なディレクトリを作成し、npm init
コマンドを実行して、Node.jsの新規プロジェクトを作成します。
$ mkdir zenhub-webhook-test
$ cd zenhub-webhook-test
$ npm init
関連パッケージのインストール
expressとbody-parserを使用するので、インストールします。
$ npm install --save express body-parser
サンプルプログラムを貼り付ける
ZenHubのサポートページではWebhookを受け取るためのサンプルプログラムが公開されているので、今回はこちらを使用します。
index.js
という名前のファイルをプロジェクトルートに作成して、そのファイルにプログラムを貼り付けます。
ZenHubIO/API: Learn how to use ZenHub's API.
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
var app = express();
http.createServer(app).listen('6000', function() {
console.log('Listening on 6000');
});
app.use(bodyParser());
app.post('*', function(req, res) {
console.dir(req.body);
});
サンプルプログラムを実行する
下記コマンドを実行すると、Webサーバーが起動します。これで一旦Webサーバー側の準備は完了です。
$ node index.js
Listening on 6000
ngrokコマンドのインストール
macOSかつHomebrewをお使いの場合はbrew cask
コマンドでインストール可能です。それ以外の場合はngrokの公式サイトでアカウント登録を行い、示された手順の通りにコマンドをインストールしてください。
c.f. ngrokが便利すぎる
$ brew cask install ngrok
ngrokコマンドを実行する
先程作成したWebサーバーはデフォルトでは6000番ポートで接続を待ち受けをしています。
ngrok http 6000
コマンドを実行することで、localhost:6000
に外部からアクセスできるようになります。
Forwarding
の項目のhttpsから始まるURLを次に使用するので、メモしておきましょう。
$ ngrok http 6000
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Session Expires 7 hours, 53 minutes
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://xxxxxxxx.ngrok.io -> localhost:6000
Forwarding https://xxxxxxxx.ngrok.io -> localhost:6000
Connections ttl opn rt1 rt5 p50 p90
1 0 0.00 0.00 120.03 120.03
HTTP Requests
-------------
ZenHubでWebhookの設定を行う
最後にZenHubのWebサイトでWebhookの設定を行います。作成したZenHubのボードを開いて、左下の自身のユーザー名を表示されているボタンを押下し、「Manage organizations」に選択します。
※下記リンクからも移動できます。
Slack & integrationsのページに移動します。Integrationsの項目を埋めていきます。
-
Select the service
Custom -
Choose a Repository to connect
連携させたGitHubリポジトリ -
Integration description
Integrationに関する説明文 (オプション) -
Webhook URL
ngrokのURL (先程メモした値)
入力が完了したら、「Add integration」を押下して、すべての設定は完了です。
実際にWebhookを受け取るテストをする
ボードに戻り、Issueのレーン移動をして、Webhookを受け取れるか確認してみます。
Review/QA
からDone
に移動させました。
下記の通りにIssueのレーン移動イベントを受け取ることができました。
$ node index.js
Listening on 6000
{ type: 'issue_transfer',
github_url: 'https://github.com/kentaro-m/auto-assign/issues/31',
organization: 'kentaro-m',
repo: 'auto-assign',
user_name: 'kentaro-m',
issue_number: '31',
issue_title: 'Error: Resource not accessible by integration',
to_pipeline_name: 'Done',
from_pipeline_name: 'Review/QA' }
実際には下記のように、特定のイベントをトリガーにGitHubやZenHubのAPIをコールして、各種リソースの状態変更を行うことが多いかと思います。
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
var app = express();
http.createServer(app).listen('6000', function() {
console.log('Listening on 6000');
});
app.use(bodyParser());
app.post('*', function(req, res) {
console.dir(req.body);
// 特定のレーンにIssueが移動したとき
if (req.body.to_pipeline_name === 'Review/QA') {
// GitHubまたはZenHubのAPIをコールして操作する
}
});
さいごに
ローカル開発環境でZenHubのWebhookを受け取る方法を紹介しました。いかがでしたか。
Webhookまわりのデバッグはリクエストを受けるエンドポイントを外部に公開しないといけないために大変な思いをしていました。ngrokを使用することで大分楽になったかと思います。
本記事がZenHubを便利に使うための仕組み作りのヒントになれば幸いです。