周りがCircleCIでマイクロサービスしている中、JenkinsおじさんとしてJenkinsfileを書き始めた。
せっかくなので?、2年前からあるけど割と情報少なめのDeclarative Pipelineという書き方で。
実際に書いてみると、情報がなくてハマったところとか、プラグイン事情が変わったりしてたところがあったので、
レシピ的にいくつか残しておく。
stages内にstageは複数書けるが、stepsは複数書けない
stageとstepsは、stageはプロジェクトのダッシュボードに出てくるけど、stepsは出てこない。
なので、パイプラインの内容をあまり知らない人にザッと伝えるためにstageの構成は重要。
で、stageを細かくしすぎると理解しづらいので、stepsを細かく分けたいと思ったところで、この結論に…。
具体的には、
stages {
stage("Aをする") {
}
stage("Bをする") {
}
}
は大丈夫だけど、
stages {
stage("Aをする") {
steps {
}
steps {
}
}
}
は書けない。
仕様っぽいので仕方ないということで、一層stageの分割はちゃんと考えたいと思った次第。
CheckstyleやFindBugs(SpotBugs)の結果集計はwarnings-ng-pluginを使う
Jenkins公式ドキュメントの Pipeline Steps Reference を見ると、
Checkstyleのプラグインがある。ただし、 Deprecated になってる。ついでにFindBugsも。
で見つけたのが、Jenkins公式で開発されている warnings-ng-plugin 。
プラグインの ng はNext Generationなので、今後はこっちを開発していく方針っぽい。
このプラグインは、静的解析ツールが出した警告や問題を収集して視覚化してくれる。
CheckstyleやFindBugs(SpotBugs)に対応しているのはもちろん、Android LintやCCM、PMDなどにも対応している。
今回は、CheckstyleとFindBugsの結果を収集してみた。
※SpotBugsじゃないのは、プロジェクトのGradleバージョンが低くて導入できなかったから…
以下の書き方で、Gradleでテストして、JUnit形式のテスト結果やJaCoCoのカバレッジ、Checkstyle、FindBugsの結果を収集できる。
できないと思ってて、いまいちだなと思っているのが、Gradleの実行がシェルスクリプト形式なこと。
これ、プラグインで対応しててほしいとこ。
本題のwarnings-ng-pluginを使っているのは、 recordIssues を使っているところ。
warnings-ng-pluginには 公式のドキュメント があるので、詳しくはそっちを見ると良い。
stage('Gradleビルドの準備、テスト') {
environment {
resultPath = "build/test-results/**/TEST-*.xml"
jacocoReportDir = "build/jacoco"
checkstyleReport = "build/checkstyle/*.xml"
findbugsReport = "build/findbugs/*.xml"
}
steps {
sh "./gradlew clean test checkstyleMain findbugsMain"
}
post {
success {
junit resultPath
jacoco execPattern: "${jacocoReportDir}/*.exec", exclusionPattern: '**/*Test.class'
recordIssues tool: checkStyle(pattern: checkstyleReport)
recordIssues tool: findBugs(pattern: findbugsReport)
}
}
}
パラメータ付きビルドはparametersブロックを使う
文字通り、パラメータ付きビルドにしたい時は、parametersブロック。
例えば、以下のように書くと、選択肢のパラメータAとテキストのパラメータBを設定できて、
Pipeline内でも params.A や params.B で参照できるようになる。
parameters
choice(name: "A", choices: ["選択肢1", "選択肢2"], description: "Aを選択してください")
text(name: "B", defaultValue: "hoge", description: "Bを入力してください")
}
環境変数を設定したい時はwithEnv
ビルド中だけ設定したい環境変数を sh 使ってexportしても良いんだけど、withEnvを使った方がスコープを狭められて良い。
注意するのは、PATHに追加したい時。この時だけは、以下の例のように PATH+EXTRA を左辺にする。
steps {
withEnv([
"HOGE=/usr/local/hoge",
"PATH+EXTRA=/hoge/bin"
]) {
// 何かやること
}
}
悩み:Dockerコンテナを脇で動かす方法がいまいち
今回のビルド、SMTPサーバをビルドの横で動かしたいけど、SMTPサーバに届いたメールは捨てたかった。
そんな時の書き方が分からず、shで済ましてしまったのが悩み。
当初は、 withDockerContainer を使おうと思ってたんだけど、これは指定したコンテナ内でジョブを動かす時用なので、
今回の用途とちょっと違う。
こんな書き方で一応動いているけど、他に良い書き方はないだろうか???
そもそもDockerの理解が薄い中なのが、さらに悩みを深くしている気はしてる。
stage("hoge") {
environment {
containerName = "smtp4jenkins"
}
steps {
sh script: "docker rm ${containerName}", returnStatus: true
sh "docker run -d -p 1080:1080 -p 25:1025 --name ${containerName} pocari/mailcatcher"
// ここで何かやる
sh "docker stop ${containerName}"
}
}
このDeclarative Pipeline周りは、公式のドキュメントが結構充実しているので、それらを参照しながら書くと効率良かった。
しばらくは、これを使って楽しくJenkinsおじさんするぞ。