システムエンジニアの子育て

子育てや、仕事、日々の生活で感じたことを発信していきます。

GitHub上のPull requestがマージされたらデプロイさせる

私が勤めている会社ではGitHubを利用しています。
プルリクエスト(以下プルリク)がマージされたら、Jenkinsでデプロイジョブを実行して検証という方法をとっていました。
面倒くさい・デプロイし忘れなど発生しており非常にナンセンスです。
そのため、GitHub + Jenkinsを使用して自動デプロイをすることで作業の効率化、手動による作業漏れを防ごうと考えました。
調べても「マージされたらデプロイ」という情報は出てこなかったため、やったことをまとめます。

実現すること

プルリクエストがmasterブランチにマージされたら自動でデプロイされる。

前提条件

  • Jenkins:2.125
  • GitHub Enterprise : 2.18
  • Jenkinsで手動デプロイジョブは作成済み
  • JenkinsジョブはPipeline

Jenkinsの設定

1.新規ジョブ作成

f:id:yamayu1027:20191203150822p:plain

f:id:yamayu1027:20191203150928p:plain

f:id:yamayu1027:20191203151343p:plain

今回は既存デプロイ処理が存在しているため、下部の「Copy from」にベースとなるジョブを指定してOKを押下する。

2.ジョブ設定

各種デプロイに必要な値を入力していく。

f:id:yamayu1027:20191203151712p:plain

f:id:yamayu1027:20191203152444p:plain

f:id:yamayu1027:20191203151841p:plain

f:id:yamayu1027:20191203152632p:plain

項目 設定
ビルドのパラメータ化 payloadをテキストで追加
古いビルドの破棄 チェックオン
Strategy Log Rotation
ビルドの保存日数 ログを保存する日数を設定
設定しなくてもよい
ビルドトリガ リモートからビルドにチェック
認証トーク リモートから実行を許可するトークンを設定。
※入力欄下部のURLはGitHub側で必要になるため記録しておくこと。
パイプライン scriptに手動デプロイによる動的パラメータが設定されている場合、固定値に変更
(デプロイするブランチを固定のものに変更するなど)
このままだとプルリクに関するイベントが全てJenkinsに送られてくるため、ジョブの実行条件に「ブランチにマージされたら」という条件を追加
https://developer.github.com/v3/activity/events/types/#pullrequestevent
を参考にパラメータを追加
mergeのトリガは、

> If the action is closed and the merged key is true, the pull request was merged.
と記載があるのでそうする。

例えば、以下のようなコードを記載すれば「masterにマージされたら」という条件になる。
(この条件が調べても全然出てこなかった・・・)

// payloadというパラメータを習得するようにしているため、payload jsonをパースする
def json = new groovy.json.JsonSlurperClassic().parseText(payload)
 
if (json.action == "closed" && json.pull_request.merged && json.pull_request.base.ref == "refs/heads/master") {
   // デプロイ処理
}

以上の設定が完了したら「保存」を押下する。

3.アクセストークン確認

画面右上のユーザー名の設定を押下する。
(画像はユーザー名をマスクしています)

f:id:yamayu1027:20191203155358p:plain

APIトークンの値を確認。
GitHub側で必要なため控えておくこと。

f:id:yamayu1027:20191203155730p:plain

これでJenkins側の設定は終了です。

GitHubの設定

1.対象repositoryのSettingsに移動

f:id:yamayu1027:20191203160356p:plain

2.HooksでAdd webhookを押下

f:id:yamayu1027:20191203160706p:plain

3.webhookを設定する

f:id:yamayu1027:20191203160854p:plain

f:id:yamayu1027:20191203160942p:plain

項目 設定値
Payload URL http://{user_id}:{user_token}@{jenkins_home}/job/{job_name}/build/buildWithParameters?token={job_token}
で設定。
content type application/x-www-form-urlencodedを選択
Which events would you like to trigger this webhook? Let me select individual events. を選択
Let me select individual events. Pull requests のみ選択
Active チェックオン

Payload URLは下記内容で設定する。

設定項目 設定値
user_id アクセストークンを確認したユーザーID
例:test
user_token Jenkins側3の設定で記録しておいたものを指定
例:aaaabbbbcccc
jenkins_home JenkinsのURL
例:http://jenkins.yamayu.net:8080
job_name Jenkins側の2の設定で記録しておいたURLを指定
日本語のジョブ名を指定している場合エンコードされている
例:auto_deploy
job_token Jenkins側の2で設定したものを使用
例:abcdefghijk

上記例の感じだとこのような感じになる。
http://test:aaaabbbbcccc@jenkins.yamayu.net:8080/job/auto_deploy/buildWithParameters?token=abcdefghijk
(urlの最後はbuildではなく、buildWithParametersにしないとpayloadの値を受け取れないため注意)

入力が完了したら「Add Webhook」を押下する

以上でGitHub側の設定完了

動作確認

GitHubでプルリクエストをマージしてみて、hookされるか確認する。

GitHub

追加したWebhookの下部のRecent Deliveriesを確認する。
成功している場合は緑色のチェックマークがつく。

f:id:yamayu1027:20191204070807p:plain

Jenkins側

追加したジョブが実行されていることを確認する。

f:id:yamayu1027:20191204071155p:plain

うまく動作していることが確認できたので完了。

まとめ

上記内容でCIが実現できました。 今回はプルリクエストがマージされたら自動デプロイを実現しましたが、payloadパラメータを使用すれば色々応用が効きそうだと感じました。
例えば、プルリクエストが作成されたら自動テストなども良いですね。
色々試していきたいと思います!