Deployments と Deployment Statuse とは
Deployments は特定の branch, sha, tag のデプロイリクエストを指す。
Deployment Statuses は Commit Status みたいに
- "success"
- "failure"
- "error"
- "pending"
というマークを Deployment に対して付けられる。
これを受け取るには deployment_status
イベントで取得する。
Deployments と Deployment Statuses はどちらも repository events に紐づけられる。
+---------+ +--------+ +-----------+ +-------------+
| Tooling | | GitHub | | 3rd Party | | Your Server |
+---------+ +--------+ +-----------+ +-------------+
| | | |
| Create Deployment | | |
|--------------------->| | |
| | | |
| Deployment Created | | |
|<---------------------| | |
| | | |
| | Deployment Event | |
| |---------------------->| |
| | | SSH+Deploys |
| | |-------------------->|
| | | |
| | Deployment Status | |
| |<----------------------| |
| | | |
| | | Deploy Completed |
| | |<--------------------|
| | | |
| | Deployment Status | |
| |<----------------------| |
| | | |
- GitHub 自体はデプロイ作業は一切しない
- 3rd party のツールとデプロイイベントとの integration を担うもの
- 複数のツールがデプロイイベントを受け取ることができる
Deployments と Deployment Statuses 使い方イメージ
例、topic ブランチをデプロイしたい
- topic ブランチ(SHA: XXXXX) をデプロイするという Deployment を作成
- Deployment id 400,
- Deployment Event 作成される
- id 400 の Deployment の状態を
pending
であることを示す Deployment Status を作成
- 実際にデプロイ開始
- デプロイ成功
- id 400 の Deployment Status
success
を作成
Deployment has many Deployment Status
必要な権限
Deployments と Deployments Statuses に必要な OAuth スコープは
repo_deployment
repo
スコープは必要ない
Develper Preview だということの Accept
deployments = client.list_deployments(
"wantedly/wantedly",
accept: "application/vnd.github.cannonball-preview+json"
)
Deployments API
以下 "octokit" gem 使って扱う例
List Deployments
client = Octokit::Client.new(
access_token: <token>
)
client.list_deployments("user/repo")
Create a Deployments
client = Octokit::Client.new(
access_token: <token>
)
payload = {
release_version: 1,
}.to_json
client.create_deployment(
"wantedly/wantedly",
"21455649bbbacdb370f1c53cbbd90b6772bef804",
{
payload: payload,
task: "deploy",
environment: "production",
}
)
デプロイ対象の ref の Commit Status が failure だと Create に失敗する
Octokit::Conflict: POST https://api.github.com/repos/wantedly/wantedly/deployments: 409 - Conflict: Commit status checks failed for master.
Error summary:
contexts: [{:context=>"continuous-integration/wercker", :state=>"failure"}]
resource: Deployment
field: required_contexts
code: invalid // See: https://developer.github.com/v3
e.errors
=> [{:contexts=>[{:context=>"continuous-integration/wercker", :state=>"pending"}], :resource=>"Deployment", :field=>"required_contexts", :code=>"invalid"}]
force deploy するには、required_contexts
に空配列を渡す []
これはつまり、required_contexts
に ["continuous-integration/wercker"]
と書くと、 wercker でのテストが通ってない commit status が failure になる。
なので、このチェックが通ってなきゃ行けないよっていう対象を空にすることで force deploy になるという理解
client.create_deployment(
<repo>,
<ref>,
{
environment: "production",
task: "deploy",
required_contexts: [],
description: "deploy request from hubot",
},
)
Update a Deployment
一度作ったらアップデートはできない
Deployment Statuses
Create a Deployment Status
client = Octokit::Client.new(
access_token: <token>
)
client.create_deployment_status(
"https://api.github.com/repos/wantedly/wantedly/deployments/44167",
"success",
{
target_url: "http://example.com/deployments/1/output",
description: "Deployment finished succesfully."
}
)
List Deployment Statuses
client = Octokit::Client.new(
access_token: <token>
)
deployment_statuses = client.list_deployment_statuses(
"https://api.github.com/repos/wantedly/wantedly/deployments/44167",
)
感想とメモ
- Deployment API
最初にいいなと思ったのは開発の履歴として git の commit があり、デプロイ履歴として deployment も github におけること。
デプロイ履歴だけなら Circle CI とか Wercker とか New Relic のデプロイ機能使えばいい気もするけど、この API が良いのは自由度が高いことかなと。application の deploy だけじゃなくて、operation も下記 task
attribute に持たせれば、何かしらチェックが通った operation code だけを実行したり、実行した operation がどうだったかの履歴を DB を使わずに作れる。 topic ブランチをデプロイするとこんな感じで pull request に deployment event が出てくる。
- Deployment の ID
最初に deployment ID をデプロイバージョンに使おうかと思ったけどDeployment の ID は全ユーザ / 全リポジトリで一意。
-
environment
について
production, staging でそれぞれどの revision 出したっけというときも、deployment を作る際に environment
も指定おけば、deployments 一覧を取って来て、staging のものだけにフィルタリングすると staging のデプロイ履歴になる。
-
target_url
について
これは後々、「何時何分の成功したデプロイのログ見たい」見たいな場合とか、ChatOps でデプロイをキックしてそのログはここで見れるよみたいな使い方ができると思う。(その出力結果を保持しておく場所の候補は S3, gist とかか)
- Deployment の
payload
payload には JSON String を渡す。Heroku のように環境変数の変更さえもデプロイと見なそうと思うとその情報もデプロイ履歴に含める必要がある。payload に諸々の設定を encrypted した JSON として入れておけばそれが実現できそう。
- Deployment に
task
という attribute がある
API ドキュメントだとちょっと古いのか載ってないけど、task
という attribute があってデフォルトだと deploy
という値が入ってる。capistrano などを使っていて deployment イベント作成後にどの rake タスクを実行するかを伝える必要がある場合に非常に便利そう。
-
required_context
について
GitHub のドキュメントの例だと、CI とセキュリティチェックを通った物だけデプロイしてるのがわかる。
-
auto_merge
について
デフォルトで true
になってる。GitHub だと topic ブランチをデプロイしてテストする際、最終的に master に merge するものだから、topic ブランチのデプロイの時点で merge したものをデプロイしてテストしてるって前に聞いた。 なので master を merge してない topic ブランチは自動で master を merge するようになってる。こんな感じで auto merge commit が作られる。