{"meta":{"title":"デプロイメントを配信する","intro":"Deployment REST APIを使用すると、サーバーおよびサードパーティアプリケーションとやり取りするカスタムツールを構築できます。","product":"REST API","breadcrumbs":[{"href":"/ja/rest","title":"REST API"},{"href":"/ja/rest/guides","title":"ガイド"},{"href":"/ja/rest/guides/delivering-deployments","title":"デプロイメントを配信する"}],"documentType":"article"},"body":"# デプロイメントを配信する\n\nDeployment REST APIを使用すると、サーバーおよびサードパーティアプリケーションとやり取りするカスタムツールを構築できます。\n\nREST API を使用して、所有するサーバー上の GitHub でホストされているプロジェクトをデプロイできます。 配置と状態を管理するエンドポイントの詳細については、「[デプロイ用の REST API エンドポイント](/ja/rest/deployments)」を参照してください。 また、この REST API を使うと、コードが既定のブランチに配置されたときに配置を調整できます。 詳しくは、「[CIサーバーの構築](/ja/rest/guides/building-a-ci-server)」をご覧ください。\n\nこのガイドでは、REST API を使って、利用できる設定を示します。\nこのシナリオでは、以下を行います。\n\n* Pull Requestをマージします。\n* CIが終了したら、それに応じてプルリクエストのステータスを設定します。\n* プルリクエストがマージされたら、サーバーでデプロイメントを実行します。\n\nこのCIシステムとホストサーバーは、想像上のものです。 Heroku でも、Amazon でも、何でも構いません。 このガイドのポイントは、通信を管理するサーバーを設定し、構成することにあります。\n\nまだ行っていない場合は必ず `ngrok` を[ダウンロードし](https://ngrok.com/)、その[使い方](https://ngrok.com/docs/getting-started/)をご確認ください。 これは、ローカル アプリケーションをインターネットに公開するために非常に便利なツールであることがわかりました。\n\n> \\[!NOTE]\n> または、Webhook 転送を使って、Webhook を受信するようにローカル環境を設定することもできます。 詳しくは、「[GitHub CLI を使用して Webhook をテスト用に転送する](/ja/webhooks/testing-and-troubleshooting-webhooks/using-the-github-cli-to-forward-webhooks-for-testing)」をご覧ください。\n\n注: このプロジェクトの完全なソース コードは、[platform-samples リポジトリから](https://github.com/github/platform-samples/tree/master/api/ruby/delivering-deployments)ダウンロードできます。\n\n## サーバーを書く\n\nローカル接続が機能していることを証明するための、簡単なSinatraアプリケーションを書きます。\nまずはこれから始めましょう。\n\n```ruby\nrequire 'sinatra'\nrequire 'json'\n\npost '/event_handler' do\n  payload = JSON.parse(params[:payload])\n  \"Well, it worked!\"\nend\n```\n\n(Sinatra のしくみに詳しくない場合は、[Sinatra ガイド](http://www.sinatrarb.com/)を読むことをお勧めします。)\n\nこのサーバーを起動してください。 既定では、Sinatra はポート `4567` で起動するため、`ngrok` もそのポートで待ち受けるように構成してください。\n\nこのサーバーが機能するには、webhookでリポジトリを設定する必要があります。 プルリクエストが作成やマージされるたびに、webhookが起動するよう設定すべきです。\n\n思う存分試せるリポジトリを作成してみましょう。 <c1><c0 /> の Spoon/Knife リポジトリはいかがでしょうか。\n\nその後、お使いのリポジトリ内に新しい Webhook を作成し、`ngrok` で提供された URL を指定し、コンテンツ タイプとして `application/x-www-form-urlencoded` を選びます。\n\n**\\[Webhook の更新]** をクリックします。\n`Well, it worked!` の本文応答が表示されます。\nすばらしい。\n**\\[個々のイベントの選択]** をクリックして、次のイベントを選択します。\n\n* デプロイ\n* \\[デプロイ ステータス]\n* プルリクエスト\n\nこれらは、関連するアクションが発生するたびにサーバーに送信 GitHub イベントです。 ここではプルリクエストがマージされたときに\\_だけ\\_処理するようにサーバーを設定します。\n\n```ruby\npost '/event_handler' do\n  @payload = JSON.parse(params[:payload])\n\n  case request.env['HTTP_X_GITHUB_EVENT']\n  when \"pull_request\"\n    if @payload[\"action\"] == \"closed\" && @payload[\"pull_request\"][\"merged\"]\n      puts \"A pull request was merged! A deployment should start now...\"\n    end\n  end\nend\n```\n\n何が起こっているのでしょうか。\nGitHubが送信するすべてのイベントには、`X-GitHub-Event` HTTP ヘッダーが添付されています。 ここではPRイベントのみに注目しましょう。 プルリクエストがマージされると (その状態は `closed` で、`merged` が `true`)、デプロイが開始されます。\n\nこの概念実証をテストするには、テスト リポジトリのブランチで何か変更を行い、プルリクエストを開いてマージします。 そうすると、サーバーはそれに応じてレスポンスを返すはずです。\n\n## デプロイメントを扱う\n\nサーバーの準備が整い、コードがレビューされ、プルリクエストがマージされたので、プロジェクトをデプロイしたいと思います。\n\nまず、イベントリスナーを修正して、プルリクエストがマージされたときに処理し、その後、デプロイメントに注意を払い始めましょう。\n\n```ruby\nwhen \"pull_request\"\n  if @payload[\"action\"] == \"closed\" && @payload[\"pull_request\"][\"merged\"]\n    start_deployment(@payload[\"pull_request\"])\n  end\nwhen \"deployment\"\n  process_deployment(@payload)\nwhen \"deployment_status\"\n  update_deployment_status\nend\n```\n\nプルリクエストからの情報に基づき、`start_deployment` メソッドを書き込むことから始めます。\n\n```ruby\ndef start_deployment(pull_request)\n  user = pull_request['user']['login']\n  payload = JSON.generate(:environment => 'production', :deploy_user => user)\n  @client.create_deployment(pull_request['head']['repo']['full_name'], pull_request['head']['sha'], {:payload => payload, :description => \"Deploying my sweet branch\"})\nend\n```\n\nデプロイには、一部のメタデータを `payload` および `description` の形式で添付できます。 これらの値はオプションですが、ログの記録や情報の表示に役立ちます。\n\n新しいデプロイメントが作成されると、まったく別のイベントがトリガーされます。 そのため、`switch` のイベント ハンドラーに新しい `deployment` ケースがあります。 この情報を使用して、デプロイメントがトリガーされたときに通知を受け取ることができます。\n\nデプロイメントにはかなり時間がかかる場合があるため、さまざまなイベント (デプロイメントがいつ作成されたか、デプロイメントの状態など) をリッスンしたいと思います。\n\n何らかの作業が行われるデプロイメントをシミュレートして、出力に対する影響を確認してみましょう。 まず、`process_deployment` メソッドを完成させます。\n\n```ruby\ndef process_deployment\n  payload = JSON.parse(@payload['payload'])\n  # you can send this information to your chat room, monitor, pager, etc.\n  puts \"Processing '#{@payload['description']}' for #{payload['deploy_user']} to #{payload['environment']}\"\n  sleep 2 # simulate work\n  @client.create_deployment_status(\"repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}\", 'pending')\n  sleep 2 # simulate work\n  @client.create_deployment_status(\"repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}\", 'success')\nend\n```\n\n最後に、ステータス情報の保存をコンソールの出力としてシミュレートします。\n\n```ruby\ndef update_deployment_status\n  puts \"Deployment status for #{@payload['id']} is #{@payload['state']}\"\nend\n```\n\n状況を細かく分解して説明しましょう。\n`start_deployment` イベントをトリガーする `deployment` によって、新しいデプロイが作成されます。 そこから、`process_deployment` を呼び出して、進行中の作業をシミュレートします。 この処理中に `create_deployment_status` も呼び出して、状態を `pending` に切り替えることで、受信者に状況を通知します。\n\nデプロイメントが完了したら、状態を `success` に設定します。\n\n## まとめ\n\nGitHub では、長年にわたってデプロイを管理するために、 `Heaven` のバージョンを使用してきました。 一般的なフローは、上記で構築したサーバーと本質的に同じです。\n\n* CIチェックのステータスに対する応答（成功もしくは失敗）を待つ\n* 必要なチェックが成功していれば、Pull Requestをマージする\n* `Heaven` マージされたコードを受け取り、ステージング サーバーと運用サーバーにデプロイします\n* それまでの間、 `Heaven` は、チャット ルームに座っている [Hubot](https://github.com/github/hubot) を介して、ビルドについて全員に通知します\n\nこれで完了です。 この例を使用するために、独自のデプロイメントを構築する必要はありません。\n\n[GitHub統合](https://github.com/integrations)に常に依存できます。"}