Skip to main content
ドキュメントには� �繁に更新が� えられ、その都度公開されています。本ページの翻訳はま� 未完成な部分があることをご了承く� さい。最新の情� �については、英語のドキュメンテーションをご参照く� さい。本ページの翻訳に問題がある� �合はこちらまでご連絡く� さい。

このバージョンの GitHub Enterprise はこの日付をもって終了となりました: 2022-06-03. 重大なセキュリティの問題に対してであっても、パッチリリースは作成されません。 パフォーマンスの向上、セキュリティの改善、新機能のためには、最新バージョンのGitHub Enterpriseにアップグレードしてく� さい。 アップグレードに関する支援については、GitHub Enterprise supportに連絡してく� さい。

デプロイメントを配信する

Deployment REST APIを使用すると、サーバーおよびサードパーティアプリケーションとやり取りするカスタ� ツールを構築できます。

Deployment APIは、GitHub Enterprise Serverにホストされたプロジェクトが、あなたのサーバーで起動できるようにします。 Status APIと組み合わせれば、コードがデフォルトブランチに到着してからすぐにデプロイメントを調整できるようになります。

このAPIでは、ステータスAPIを使って、利用できる設定を示します。 このシナリオでは、以下を行います。

  • Pull Requestをマージします。
  • CIが終了したら、それに応じてプルリクエストのステータスを設定します。
  • プルリクエストがマージされたら、サーバーでデプロイメントを実行します。

このCIシステ� とホストサーバーは、想像上のものです。 Herokuでも、Amazonでも、何でも構いません。 このガイドのポイントは、通信を管理するサーバーを設定し、構成することにあります。

ま� ngrokをダウンロードしていない� �合はダウンロードし、その使いかたを学びましょう。 これはローカル接続を公開するために非常に役立つツール� と思います。

注釈: このプロジェクトの完全なソースコードは、platform-samplesリポジトリからダウンロードできます。

サーバーを書く

ローカル接続が機能していることを証明するための、簡単なSinatraアプリケーションを書きます。 まずは以下のソースから始めましょう。

require 'sinatra'
require 'json'

post '/event_handler' do
  payload = JSON.parse(params[:payload])
  "Well, it worked!"
end

(シナトラの仕組みに詳しくない方は、Sinatraのガイドを読むことをお勧めします。)

このサーバーを起動してく� さい。 デフォルトでは、Sinatraはポート4567で起動するため、このポートもリッスンを開始するようngrokを設定するとよいでしょう。

このサーバーが機能するには、webhookでリポジトリを設定する必要があります。 プルリクエストが作成やマージされるたびに、webhookが起動するよう設定すべきです。 なんでも好きにして構わないようなリポジトリを作成しましょう。 @octocat's Spoon/Knifeリポジトリなどはどうでしょうか。 その後、リポジトリ内に新しいwebhookを作成し、ngrokが提供したURLを指定し、コンテンツタイプとしてapplication/x-www-form-urlencodedを選択します。

新しいngrok URL

Update webhook(webhookの更新)をクリックしてく� さい。 本文にWell, it worked!というレスポンスが表示されるはずです。 これでうまくいきました。 [Let me select individual events]をクリックし、以下を選択します。

  • デプロイメント
  • デプロイメントステータス
  • プルリクエスト

これらは、関係するアクションが発生するごとにGitHub Enterprise Serverがこのサーバーに送信するイベントです。 ここではプルリクエストがマージされたときの処理� けを処理するようサーバーを設定します。

post '/event_handler' do
  @payload = JSON.parse(params[:payload])

  case request.env['HTTP_X_GITHUB_EVENT']
  when "pull_request"
    if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
      puts "A pull request was merged! A deployment should start now..."
    end
  end
end

さて、ここで起こっていることを説明しましょう。 GitHub Enterprise Serverが送信するすべてのイベントには、X-GitHub-Event HTTPヘッダが添付されています。 ここではPRイベントのみに注目しましょう。 プルリクエストがマージされると (ステータスがclosedとなり、mergedtrueになると)、デプロイメントを開始します。

この概念実証を試すため、テストリポジトリのブランチで何か変更を行い、プルリクエストを開いてマージします。 そうすると、サーバーはそれに応じてレスポンスを返すはずです。

デプロイメントを扱う

サーバーの準備が整い、コードがレビューされ、プルリクエストがマージされたので、プロジェクトをデプロイしたいと思います。

まず、イベントリスナーを修正し、マージされたときにプルリクエストを処理して、デプロイメントの待機を開始することから始めましょう。

when "pull_request"
  if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
    start_deployment(@payload["pull_request"])
  end
when "deployment"
  process_deployment(@payload)
when "deployment_status"
  update_deployment_status
end

プルリクエストからの情� �に基づき、start_deploymentメソッドを書き込むことから始めます。

def start_deployment(pull_request)
  user = pull_request['user']['login']
  payload = JSON.generate(:environment => 'production', :deploy_user => user)
  @client.create_deployment(pull_request['head']['repo']['full_name'], pull_request['head']['sha'], {:payload => payload, :description => "Deploying my sweet branch"})
end

デプロイメントには、payloadおよびdescriptionの形式で、一部のメタデータを添付できます。 これらの値はオプションですが、ログの記録や情� �の表示に役立ちます。

新しいデプロイメントが作成されると、まったく別のイベントがトリガーされます。 ですから、deploymentのために、イベントハンドラーのswitchに新たなcaseを用意します。 この情� �を使用して、デプロイメントがトリガーされたときに通知を受け取ることができます。

デプロイメントにはかなり時間がかかる� �合があるため、デプロイメントがいつ作成されたか、デプロイメントのステータスなどのさまざまなイベントをリッスンしたいと思います。

何かの作業をするデプロイメントをシミュレートし、その影響を出力として通知しましょう。 まず、process_deploymentメソッドを完成させます。

def process_deployment
  payload = JSON.parse(@payload['payload'])
  # you can send this information to your chat room, monitor, pager, etc.
  puts "Processing '#{@payload['description']}' for #{payload['deploy_user']} to #{payload['environment']}"
  sleep 2 # simulate work
  @client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'pending')
  sleep 2 # simulate work
  @client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'success')
end

最後に、ステータス情� �の保存をコンソールの出力としてシミュレートします。

def update_deployment_status
  puts "Deployment status for #{@payload['id']} is #{@payload['state']}"
end

ここの処理を細かく説明しましょう。 新しいデプロイメントがstart_deploymentにより作成され、それがdeploymentイベントをトリガーします。 そこからprocess_deploymentを呼び出して、実行中の作業をシミュレートします。 この処理の間にcreate_deployment_statusも呼び出し、ステータスをpendingに切り替えることで受信側に状態を通知します。

デプロイメントが完了後、ステータスをsuccessに設定します。

おわりに

GitHubでは長年、デプロイメントを管理するためHeavenの特定のバージョンを使用してきました。 一般的なフローは、上で構築したサーバーと本質的に同じです。

  • CIチェックのステータスに対する応答(成功もしくは失敗)を待つ
  • 必要なチェックが成功していれば、Pull Requestをマージする
  • Heavenはマージされたコードを取り込み、ステージング及びプロダクションサーバーにデプロイする
  • その間にHeavenは、当社のチャットルー� に居座っているHubotを通じて全員にビルドについて通知する

これで完了です。 この例を使用するために、独自のデプロイメントを構築する必要はありません。 いつでもGitHubインテグレーションに� �ることができます。