タイトル通りです。
やりたいこと
- ローカルからGitHubのdevelopブランチへpush
- GitHubがWebhookでJenkinsに通知を行う
- push先の判断
- unittest実行
- masterにマージ
- Herokuへデプロイ
3~5がJenkinsで実行するジョブ単位です。ついでに各ジョブの実行をSlackで通知します。
3. push先の判断
これは補助的なジョブです。
役割としてはGitHubへのpush先ブランチがdevelopかmasterかを判断するだけです。developであればビルド成功、masterであれば不安定ビルドで終了します。
本来であればGitHubとJenkinsの連携に「Git Plugin」または「GitHub Plugin」を使おうと思ったのですが、GitHub側がServeicesをWebhooksに統合してしまったようです。これらのPluginであればGitHub側でブランチを指定できたようなのですが。残念。
Webhooksでは多様なイベントをトリガーにできますが、ブランチの指定ができません。Jenkins側でパラメータを見てブランチを判断することになりますが、masterにしろdevelopにしろ、ビルドは行わなずともジョブが走ってしまうのです。「5. masterにマージ」のジョブが実行される度に失敗記録が積み上がるのも嫌なので、今回は全体制御用にこのジョブを作成しています。
他にいい方法があれば教えて下さい。
Jenkinsの設定
GitHubの設定
- Settings>Webhooksより「Add webhook」を選択してURLを以下の形式で入力します。 TOKEN_NAMEはジョブの設定で指定する認証トークンです。
http://[USER_ID]:[API_TOKEN]@[JENKINS_HOST]/job/[JOB_NAME]/buildWithParameters?token=[TOKEN_NAME]
ジョブの設定
今回作成するジョブは全てフリースタイルプロジェクトです。
- General
「ビルドのパラメータ化」にチェックを入れてテキスト形式で名称はpayloadとしておきます。 - ビルド・トリガ
「リモートからビルド」にチェックを入れて認証トークンに適当な値を入力します。この認証トークンがGitHubの設定で使うTOKEN_NAMEです。 - ビルド
「シェルの実行」を選択し下記の通りシェルを書いて「Exit code to set build unstabl」には「1」を設定します。これによりdevelop以外にpushされた場合にはexit code=1
でシェルが終了しジョブの実行結果が不安定ビルドになります。
if [[ ${payload} =~ .*\"ref\":\"refs/heads/develop\".* ]]; then exit 0 fi exit 1
上がdevelopで下がmasterからのpushです。masterがunstableになっているのでOK。
このジョブではSlack通知を行わないため、以上で設定は終了です。
4. unittest実行
事前準備
- EC2にPython3系を入れておきます。
$ sudo yum update $ sudo yum install python3
- Jenkinsに「ShiningPandas Plugin」をインストール。Jenkinsの管理>Global Tool ConfigurationよりPython3を追加します。
以上で、EC2上のJenkinsでPython3を使えるようになります。
ジョブの設定
- ソースコード管理
Gitを選択しリポジトリURLには先程と同じURLを入れます。ビルドするブランチはdevelopです。 - ビルド・トリガ
「他のプロジェクトの後にビルド」を選択し、対象プロジェクトには「3. push先の判断」のジョブを指定し「安定している場合のみ起動」とします。これでdevelopにpushされた時のみこのジョブが実行されるようになります。 - ビルド
「Virtualenv Builder」を追加します。Python3を選択して以下のシェルを入力。
pip install -r requirements.txt coverage run --source='dokipro1' -m xmlrunner -o test-reports coverage xml -o coverage/result.xml
- ビルド後の処理
「JUnitテスト結果の集計」「Coberturaカバレッジ・レポートの集計」を追加します。これらの設定はリソースパスを指定するだけです。そして「Slack Notification」も追加します。これでSlackにビルド通知が飛びます。
5. masterにマージ
排他とかどうするんだろうと思ったけど、このプロジェクトの開発者は私一人なので考えないことにします。
ジョブの設定
- ソースコード管理
先程のジョブと同じようにURLを設定。今回は認証情報としてGitHubのアカウントを追加します。cloneだけなら問題ないですがpush時に必要となるためです。追加処理から「Meger before build」を選択し、masterにmergeするようにしておきます。 - ビルド後の処理
「Git Publisher」を追加します。「ビルド成功時のみプッシュ」「結果をマージ」を選択し「ブランチ」でoriginのmasterを指定します。「Slack Notifications」も追加。Slack通知もにぎやかになってきました。
6. Herokuへデプロイ
最後のジョブです。Herokuの便利機能を使います。
Herkokuのダッシュボード>Deployから「Automatic deploys」を有効にするだけです。これで指定したブランチにコミットがあった場合に、自動でデプロイをしてくれます。今回はmasterを設定。
Slackへの通知も行おうとしましたが失敗しました。また今度挑戦します。
おわりに
躓きながらで結構時間がかかってしまった。
「3. push先の判断」を「4. unittest実行」から切り出したことは、Webhookトリガーへの依存性が排除され、部品としての独立性がたかまったので良かったと思う。
「5. masterにマージ」と「6. Herokuへデプロイ」は一緒でもいいんじゃない?て思うけど、ここまでで疲れていたのでHerokuのCLI周りが面倒だった。
今度はPipelineで置き換えしてみたい。