はじめに
このガイドは、GitHub Appをビルドしてサーバー上で実行するのに役立ちます。 ビルドするアプリケーションは、アプリケーションがインストールされたリポジトリでオープンされたすべての新しいIssueにラベルを付けます。
このプロジェクトでは、以下を見ていきます。
- イベントを待ち受けるアプリケーションのプログラミング
- Octokit.rbライブラリを使ったREST APIの操作の実行
ノート: このガイドは、Rubyプログラミング言語を使ったアプリケーションの開発プロセスを示します。 しかし、Octokitのバラエティはたくさんあります。 JavaScriptが好きなのであれば、GitHub Appsを開発するためにProbot及びNode.jsを使うことができます。
以下のステップを行っていけば、GitHub APIの完全な一式を使って他の種類のインテグレーションを開発する準備が整います。
必要な環境
以下に関する基本的な理解があると役立つでしょう。
とはいえ、経験のレベルにかかわらず見ていくことはできます。 その過程で必要な情報にはリンクしていきます!
始める前に、以下を行っておく必要があります。
-
Using the GitHub API in your appリポジトリのクローン。
$ git clone https://github.com/github-developer/using-the-github-api-in-your-app.git
ディレクトリの中には、このクイックスタートで使用する
template_server.rb
ファイルと、完成したプロジェクトコードであるserver.rb
ファイルがあります。 -
開発環境のセットアップクイックスタート中のステップに従い、
template_server.rb
アプリケーションサーバーを設定し、実行してください。 開発環境のセットアップ以外のGitHub Appクイックスタートを完了させたことがあるなら、_新しい_GitHub Appを登録して、このクイックスタートで使う新しいSmeeチャンネルを開始してください。このクイックスタートには、開発環境のセットアップクイックスタートと同じ
template_server.rb
コードが含まれています。 ノート: 開発環境のセットアップクイックスタートを見ていく際には、必ずUsing the GitHub API in your appリポジトリに含まれているプロジェクトをファイルを使ってください。テンプレートのGitHub Appのセットアップで問題が生じた場合は、トラブルシューティングのセクションを参照してください。
アプリケーションのビルド
template_server.rb
のコードに馴染んだところで、アプリケーションがインストールされたリポジトリでオープンされたすべてのIssueに自動的にneeds-response
ラベルを追加するコードを作成しましょう。
template_server.rb
ファイルには、まだカスタマイズされていないアプリケーションのテンプレートコードが含まれています。 このファイルには、webhookイベントを処理するためのプレースホルダーのコードや、Octokit.rbクライアントを初期化する他のコードが含まれています。
ノート: template_server.rb
には、このガイドを補完し、追加の技術的な詳細を説明する多くのコードコメントが含まれています。 このセクションの先に進む前に、コードの動作の概要をつかむために、この時点でこのファイル中のコメントを読み通しておくと役立つかもしれません。
このガイドの終わりに作成することになるカスタマイズされた最終のコードは、server.rb
にあります。 とはいえ、最後までそれを見るのは待ってみてください!
以下が、最初のGitHub Appを作成するまでに行うステップです。
ステップ 1. アプリケーションの権限の更新
最初にアプリケーションを登録した際は、デフォルトの権限を受け入れています。これは、アプリケーションがほとんどのリソースにアクセスできないことを意味します。 この例においては、アプリケーションはIssueを読み、ラベルを書く権限を必要とします。
アプリケーションの権限を更新するには、以下の手順に従います。
- アプリケーションの設定ページからアプリケーションを選択肢、サイドバーの [Permissions & Webhooks] をクリックします。
- "Permissions(権限)"セクションで"Issues"を見つけ、隣の"Access(アクセス)"ドロップダウンでRead & Write(読み書き)を選択してください。 このオプションはIssueとラベルの両方へのアクセスを許可するものと説明されており、これはまさに必要なことです。
- "Subscribe to events(イベントのサブスクライブ)"セクションで、Issuesを選択してこのイベントをサブスクライブしてください。
- ページの下部でSave changes(変更を保存)をクリックしてください。
- アプリケーションを自分のアカウントにインストールしたなら、メールをチェックして、新しい権限を受諾するリンクに従ってください。 アプリケーションの権限あるいはwebhookを変更した場合、そのアプリケーションをインストールしたユーザ(自分自身を含む)は、変更が有効になる前に新しい権限を承認しなければなりません。 インストールページにアクセスして、アプリケーションの隣の"Configure(設定)"をクリックしても、新しい権限を承認できます。 アプリケーションが異なる権限を要求していることを知らせるバナーがページの上部に表示されます。 "Details(詳細)"をクリックし、"Accept new permissions(新しい権限を承認)"をクリックしてください。
これでうまくいきました。 アプリケーションは必要なタスクを実行する権限を所有しています。 これで、アプリケーションを動作させるコードを追加できるようになりました。
ステップ 2. イベント処理の追加
アプリケーションが最初にやらなければならないのは、オープンされた新しいIssueを待ち受けることです。 Issuesイベントにサブスクライブしたので、issues
webhookを受信し始めることになります。このイベントは、特定のIssueに関連するアクションが生じたときにトリガーされます。 コード中にほしい特定のアクションに対してこのイベントの種類をフィルターできます。
GitHub は webhook ペイロードを POST
リクエストとして送信します。 Smeeのwebhookペイロードはhttp://localhost/event_handler:3000
に転送しているので、サーバーはこのPOST
リクエストのペイロードをpost '/event_handler'
ルートで受け取ります。
空の post '/event_handler'
ルートは、必要な環境セクションでダウンロードした template_server.rb
ファイルに既に含まれています。 空のルートは次のようになっています。
post '/event_handler' do
# # # # # # # # # # # #
# ADD YOUR CODE HERE #
# # # # # # # # # # # #
200 # success status
end
以下のコードを追加することで、このルートを使ってissues
イベントを処理してください。
case request.env['HTTP_X_GITHUB_EVENT']
when 'issues'
if @payload['action'] === 'opened'
handle_issue_opened_event(@payload)
end
end
GitHub が送信する全てのイベントには、HTTP_X_GITHUB_EVENT
というリクエストヘッダが含まれており、これは POST
リクエストのイベントの型を示します。 この時点では、関心があるのはissues
というイベントの種類だけです。 各イベントには、アクションをトリガーしたイベントのタイプを示す action
フィールドが付いています。 issues
の場合、action
フィールドはassigned
、unassigned
、labeled
、unlabeled
、opened
、edited
、milestoned
、demilestoned
、closed
、reopened
のいずれかです。
イベントハンドラをテストするには、一時的なヘルパーメソッドを追加してみてください。 後でラベルの処理を追加するときに更新します。 この時点では、以下のコードをhelpers do
セクションの中に追加してください。 他の任意のヘルパーメソッドの前後に新しいメソッドを追加できます。 順序は問題ではありません。
def handle_issue_opened_event(payload)
logger.debug 'An issue was opened!'
end
このメソッドはJSON形式のイベントペイロードを引数として受け取ります。 これは、メソッド中でペイロードをパースして、任意の必要なデータへとドリルダウンしていけるということです。 どこかの時点でペイロード全体を調べると役立つかもしれません。logger.debug 'An issue was opened!
をlogger.debug payload
に変更してみてください。 出力されるペイロードの構造は、issues
webhookイベントのドキュメントに示されているものと一致しているはずです。
これでうまくいきました。 変更をテストしてみましょう。
ノート: 変更をテストする前に、Sinatraサーバーを再起動しなければなりません。 Ctrl-C
を入力してサーバーを停止し、ruby template_server.rb
をもう一度実行してください。 アプリエーションのコードを変更するたびにこれを繰り返したくないなら、リローディングを調べてみてください。
ブラウザで、アプリケーションをインストールしたリポジトリにアクセスしてください。 そのリポジトリで新しいIssueをオープンしてください。 そのIssueは好きな内容でかまいません。 これは単にテストにすぎません。
ターミナルを見直してみれば、An issue was opened!
というメッセージが出力にあるはずです。おめでとうございます! アプリケーションにイベントハンドラを追加できました。 💪
ステップ 3. 新しいラベルの作成
これで、アプリケーションはIssueがオープンされたときを示せるようになりました。 今度は、アプリケーションがインストールされたリポジトリのあらゆる新しくオープンされたIssueにneeds-response
というラベルを追加しましょう。
ラベルをどこでも追加できるようにするには、リポジトリでカスタムラベルを作成しなければなりません。 これをする必要があるのは一度だけです。 このガイドのためには、ラベルをGitHub上で手動で作成します。 リポジトリでIssuesをクリックして、続いてLabelsを、そしてNew label(新規ラベル)をクリックしてください。 新しいラベルの名前をneeds-response
にしてください。
Tip: アプリケーションがラベルをプログラムから作成できたら素晴らしいのではないでしょうか? できます! このガイドのステップを終えた後に、自分でそのためのコードを追加してみてください。
これでラベルができたので、REST APIを使って新しくオープンされたすべてのIssueにラベルを追加するようにアプリケーションをプログラムできます。
ステップ 4. ラベルの処理の追加
おめでとうございます。最後のステップである、アプリケーションへのラベル処理の追加にまで来ました。 このタスクのためには、Octokit.rb Rubyライブラリを使いましょう。
Octokit.rbのドキュメントで、ラベルメソッドのリストを見つけてください。 使うメソッドはadd_labels_to_an_issue
です。
template_server.rb
に戻って、以前に定義したメソッドを見つけてください。
def handle_issue_opened_event(payload)
logger.debug 'An issue was opened!'
end
add_labels_to_an_issue
のドキュメントには、このメソッドに3つの引数を渡さなければならないとあります。
- Repo (
"owner/name"
という形式のstring) - Issue number(integer)
- Labels (array)
ペイロードをパースすれば、リポジトリとIssue番号を取得できます。 ラベル名は常に同じ(needs-response
)なので、labels配列にハードコードした文字列で渡せます。 これらのピースをまとめると、更新されたメソッドは以下のようになるでしょう。
# Issueがオープンされたらラベルを追加
def handle_issue_opened_event(payload)
repo = payload['repository']['full_name']
issue_number = payload['issue']['number']
@installation_client.add_labels_to_an_issue(repo, issue_number, ['needs-response'])
end
新しいIssueをテストのリポジトリでオープンして、何が起こるか見てみてください! もしすぐには何も起こらなければ、リフレッシュしてみてください。
ターミナルにはあまり表示されませんが、とはいえボットユーザがラベルをIssueに追加したことはわかります。
ノート: GitHub AppがAPIを介してラベルの追加といったアクションを起こした場合、GitHubはそれらのアクションをボットアカウントが行ったものと示します。 詳しい情報については「マシン対ボットアカウント」を参照してください。
そうなっていたら、おめでとうございます! 動作するアプリケーションの構築に成功しました! 🎉
server.rb
の最終のコードはアプリケーションのテンプレートリポジトリにあります。
ここから進む先に関するアイデアについては「次のステップ」を参照してください。
トラブルシューティング
以下は、いくつかの一般的な問題と推奨される解決策です。 他の問題が生じた場合は、GitHub API Development and Support Forumで助けやアドバイスを求めることができます。
-
Q: サーバーがイベントを待ち受けていません! Smeeクライアントはターミナルウィンドウで動作していて、新しいIssueをオープンしてGitHub.com上でイベントを送信していますが、サーバーを動作させているターミナルウィンドウに出力がありません。
A: アプリケーション設定のSmeeドメインが正しくないかもしれません。 アプリケーション設定ページにアクセスし、Register a new app with GitHub(GitHubに新しいアプリケーションを登録)にあるフィイールドをダブルチェックしてください。 それらのフィールドのドメインが、「新しいSmeeチャンネルの開始」の
smee -u <unique_channel>
で使ったドメインと一致していることを確認してください。 -
Q: アプリケーションが動きません! 新しいIssueをオープンしましたが、リフレッシュしてもラベルが追加されません。
A: 以下のようになっていることをすべて確認してください。
- Issueをオープンしているリポジトリにアプリケーションをインストールしたこと。
- ターミナルウィンドウでSmeeクライアントが動作していること。
- 他のターミナルウィンドウでWebサーバーが動作していること。
- アプリケーションがIssueの読み書き権限を持っており、issueイベントをサブスクライブしていること。
- 権限を更新した後にメールを確認して新しい権限を承認したこと。
おわりに
このガイドを見終えれば、GitHub Appを開発するための基本的なビルディングブロックを学んだことになります! 振り返ると、以下を行いました。
- イベントを待ち受けるようにアプリケーションをプログラム
- Octokit.rbライブラリを使ったREST APIの操作
次のステップ
以下は、次に行えることのいくつかのアイデアです。
- GraphQLを使ってアプリケーションを書き直す!
- Probotを使ってNode.jsでアプリケーションを書き直す!
- アプリケーションが
needs-response
ラベルがIssueにすでに付いているかを確認して、なければ追加するようにする。 - ボットがラベルを追加できたら、ターミナルにメッセージを表示する。 (ヒント:
needs-response
ラベルのIDをペイロード中のラベルのIDと比較してメッセージの条件とし、他のラベルではなく関連するラベルが追加されたときにのみメッセージを表示してください) - アプリケーションにランディングページを追加し、Sinatraのルートをそこに接続する。
- コードをホストされたサーバー(Herokuのような)に移す。 新しいドメインでアプリケーションの設定を更新するのを忘れないようにしてください。
- GitHub API Development and Support Forumでプロジェクトを共有したりアドバイスをもらったりする。