#oyasuminase

駆け出しオタクエンジニア

2020-12-26ログ:MacにVirtualBoxでCentos7を建てる

MacVirtualBoxでCentos7を建てる

環境

作業内容

VirtualBoxのインストール

既にインストール済みだった。

$ VBoxManage -v
6.1.4r136177

CentOS7のダウンロード

www.centos.org

仮想マシンの作成

新規から作成。

  • タイプ:Linux
  •  バージョン:Red Hat(64-bit)
  • メモリ:1024MB
  • 仮想ハードディスク:VDI・可変サイズ・8GB

作成後にマシンを選択して設定>ストレージから「コントローラ:IDE」にインストールしたCentOSのディスクイメージを設定。

仮想マシンの設定変更

設定>ディスプレイから「表示倍率」を250%に変更

以上

GitHubへのpushをトリガーにJenkinsでテストを実行しmasterにマージしてHerokuへデプロイする

タイトル通りです。「Jenkins+Python+unittest」の記事のまとめみたいな。

やりたいこと

  1. ローカルからGitHubのdevelopブランチへpush
  2. GitHubがWebhookでJenkinsに通知を行う
  3. push先の判断
  4. unittest実行
  5. masterにマージ
  6. Herokuへデプロイ

3~5がJenkinsで実行するジョブ単位です。ついでに各ジョブの実行をSlackで通知します。

3. push先の判断

これは補助的なジョブです。役割としてはGitHubへのpush先ブランチがdevelopかmasterかを判断するだけです。developであればビルド成功、masterであれば不安定ビルドで終了します。

本来であればGitHubとJenkinsの連携に「Git Plugin」または「GitHub Plugin」を使おうと思ったのですが、GitHub側がServeicesをWebhooksに統合してしまったようです。これらのPluginであればGitHub側でブランチを指定できたようなのですが。

developer.github.com

Webhooksでは多様なイベントをトリガーにできますがブランチの指定ができません。Jenkins側でパラメータを見てブランチを判断することになりますが、masterでもdevelopでもビルドは行わなくてもジョブが走ってしまうのです。「5. masterにマージ」のジョブが実行される度に失敗記録が積み上がるのも嫌なので今回は全体制御用にこのジョブを作成しています。

他にいい方法があれば教えて下さい。

Jenkinsの設定

  • 「Conditional BuildStep」をインストール。
  • ユーザーの管理より「Add new Token」を選択してAPIトークンを取得。

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

f:id:ppine:20200503143302p:plain

上が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で置き換えしてみたい。

Jenkins+Python+unittest最後

(2020/05/06:追記)こっちを見たほうが良いです。

oyasuminase.hatenablog.com


続きです。

oyasuminase.hatenablog.com

GitHubのdevelopへのpushをトリガーにJenkinsのジョブを実行します。

1. unittet実行

Jenkins

  • Jenkinsの管理>プラグインの管理より「Conditional BuildStep」をインストール。
  • Jenkinsの管理>ユーザーの管理>(ユーザー)>設定>より「Add new Token」を選択してJenkinsにアクセスするためのAPIトークンを取得する。
  • ジョブ>設定>ビルド・トリガの「リモートからビルドにチェック」してURLをメモする。
  • ビルド手順の追加より「Conditional step(Single)」を選択して下記の通り設定。
項目
Run? Regular Expression Match
Expression ."ref":"refs\/heads\/develop".
Label ${ENV,var="payload"}
On evaluation failure Don't run
Builder Virtualenv Builder

shellは前と同じ内容です。

pip install -r requirements.txt
coverage run --source='dokipro1' -m xmlrunner -o test-reports
coverage xml -o coverage/result.xml

GitHub

  • リポジトリ>Settings>Webhooksより「Add webhook」を選択してい先程メモしたURLとAPIトークンを設定する。

ジョブの実行

以上で設定は完了です。試しにdevelopにpushしてみます。空コミットが便利です。

$ git commit --allow-empty -m '[Dev] Jenkins連携テスト'
$ git push origin develop

Jenkinsから確認したとこと無事にジョブが実行されていました。

さて、本当はこの後developをmasterにマージするジョブを作りたかったのですが問題が発生しました。masterにマージしてpushするとこの記事で作っている単体テストジョブが実行されてしまいます。ちょっとJenkinsの実行トリガーから考え直さなければいけなくなりましたのでここまで。

Jenkins+Python+unittest番外編

(2020/05/06:追記)こっちを見たほうが良いです。

oyasuminase.hatenablog.com


coverageの集計が間違っていたました。

oyasuminase.hatenablog.com

明らかに対象のファイル数が多いと思ったらライブラリも集計対象になってた。

coverage run --source='dokipro1' -m xmlrunner -o test-reports

対象のパスをちゃんと指定しなきゃですね。これでOKでした。

Jenkins+Python+unittest続き

(2020/05/06:追記)こっちを見たほうが良いです。

oyasuminase.hatenablog.com


続きです。 oyasuminase.hatenablog.com unittestの結果とCoverageをxml形式で出力しJenkins上で結果をいい感じに確認します。

unittest-xml-reportingのインストール

テスト結果をxml形式で出力できるライブラリをインストールします。

$ pip install unittest-xml-reporting

コードの修正。

if __name__ == '__main__':
    unittest.main(testRunner=xmlrunner.XMLTestRunner(output="./test-reports"))

ついでにテストケースを一箇所失敗するようにしておきました。

coveragreのインストール

coverageの方もいれていきます。

$ pip install coverage

ジョブの設定

  1. Jenkinsの管理>プラグインの管理より「Cobertura Plugin」を検索してインストール。
  2. ジョブ>設定>ビルド後の処理に「JUnitテスト結果の集計」を追加。
  3. ジョブ>設定>ビルド後の処理に「Cobertura カバレッジ・レポートの集計」を追加。
  4. ジョブ>設定>ビルドスクリプトの修正。
pip install -r requirements.txt
coverage run -m xmlrunner -o test-reports
coverage xml -o coverage/result.xml

ジョブを実行すると f:id:ppine:20200430013328p:plain

こんな感じ。