読者です 読者をやめる 読者になる 読者になる

Jenkins2でpipelineを使ってビルドするやりかた

Jenkins

概要

先日Jenkins2がリリースされました。 今はまだJenkins1系を使っているのですが、Jenkins2でビルド時にpipelineを使えるということで、一部のジョブをJenkins2に移行してみました。 主にビルドのpipelineの設定を備忘録として残します。

移行したジョブの概要

移行したプロジェクトは3のジョブから構成されており、それぞれ以下の様な役割があります。 処理が3つのジョブに別れるためpipelineプラグインをインストールしています。

ジョブその1 ビルド&アーカイブ

SpringBootアプリケーションでGradleでビルドしています。 JUnitのテスト結果の保存と、下流ジョブにファイルを渡すためDockefile、Docker操作用のpythonスクリプトをアーカイブしています。

ジョブその2 Dockerイメージのビルド

ジョブその1から渡されたDockerファイルを元にイメージをビルドしています。

ジョブその3 Dockerコンテナの停止&起動

ジョブその1から渡されたDocker操作用のpythonスクリプトを実行しています。

特に難しい処理はしていませんが、ワークスペースのアーカイブプラグインと、pipelineプラグインは別途インストールした記憶があります。
また、pipelineプラグインはjQueryのバージョンが微妙に合っておらず、ポップアップ処理が動きません。マイグレーションのプラグインもインストールしたのですが改善されず・・・。

enkins2での設定

Jenkins2のインストール

Jenkins2は2.1のwarファイルをダウンロードして起動しています。
インストール時のプラグインインストールはおすすめを選択したので、自分でプラグインのインストールは行っていません。

#!/bin/sh

export JENKINS_HOME=./jenkins_home
export JAVA_HOME=/usr/java/jdk8
export PATH=$PATH:$JAVA_HOME/bin
java -jar latest.war --httpPort=38080 --prefix=/jenkins2 -Xmx512m

こんなシェルスクリプトを準備して起動しています。
これでhttp://ホスト:38080/jenkins2/
でアクセスできます。オフィシャルのDockerイメージもあるので、画面だけ見たいという人はイメージ使ったほうがよりお手軽に見れます。

pipelineジョブの作成

ジョブを作るときにpipelineというジョブが選択できるので、これを選択します。 f:id:beeete2:20160709102443p:plain

pipelineの設定画面で、pipelineの処理内容をGroovyで設定します。 f:id:beeete2:20160709102517p:plain

自分が設定した内容はこんな感じにしました。

node {
   // Checkoutステージを定義
   stage 'Checkout'
   // 
   git url: 'レポジトリアドレス'
   // build.gradleからバージョンを取得
   def applicationVersion = version()
   if (!applicationVersion) {
       error message: 'version colud not be found.'
   }

   // Buildステージを定義
   stage 'Build'
   // npm instlalを実行
   sh "npm install"
   // gradlewを実行
   sh "./gradlew clean build -Penv=production"
   // JUnitテストレポートを保存
   step([$class: 'JUnitResultArchiver', testResults: '**/build/test-results/*.xml'])
   // ワークスペース内のファイルをアーカイブ
   step([$class: 'ArtifactArchiver', artifacts: 'build/libs/*.jar, Dockerfile, docker.py', onlyIfSuccessful: true, allowEmptyArchive: false])
   
   // Build Dockerステージを定義
   stage 'Build Docker'
   // inputを使って実行するかを選択
   input message: "Do you want to build a version[p2p-web:${applicationVersion}] of the image ?"
   // docker buildを実行
   sh "docker build -t p2p-web:${applicationVersion} ."
   
   // Run Dockerステージを定義
   stage 'Run Docker'
   // inputを使って実行するかを選択
   input message: "Do you want to run a version[p2p-web:${applicationVersion}] of the container?"
   // docker.pyを実行
   sh "python docker.py ${applicationVersion}"
}
def version() {
    def matcher = readFile('build.gradle') =~ "def applicationVersion = '(.+)'"
    matcher ? matcher[0][1] : null
}

pipelineの簡単な説明です。

stage

パイプラインのジョブみたいな感じ。

git

レポジトリからcloneしています。 以下のようにすることで特定のブランチをcheckoutすることができます。

git branch: "ブランチ名", url: 'レポジトリ'

sh

名のごとくコマンドを実行。

step

JUnitやアーカイブなどの処理を呼び出し。

input

Yes / Noのプロンプトを表示して、処理をすすめるか中断(abort)するか選択させる。 ビルド&テストまで行って、アプリケーションをデプロイするかはプロンプトで選択させるという時に使えるかと思います。

ちなみに、プロンプトはこんな感じになります。 f:id:beeete2:20160709102658p:plain [Proceed]を選択すると次の処理に進みますが、[Abort]を選択するとここで終了します。pipelineのステータスは中断(灰色)となります。

上のパイプラインを実行すると、こんな感じの画面になります。 f:id:beeete2:20160709102745p:plain jenkins1時代のジョブの画面と大きく変わっている部分としてStage Viewが追加され設定したpipelineの内容にしたがって結果が表示されます。
どこで失敗したかわかると思います。
また、今回パイプラインのスクリプトはJenkins内に保存しましたが、レポジトリにJenkinsfileというファイルを準備して実行させることもできるみたいです。

わからなかったこと

しっかりとドキュメントを読めてないので、もしかしたら解決法があるかもしれません。

pipelineからサードーパーティのプラグインを呼び出す方法がわからなかった。

Jacocoを使ってコードカバレッジをとっているジョブもあるのですが、pipelineでJacocoのプラグインを呼び出す方法がわかりませんでした。
あとはHipChatの通知系も呼び出したいなーと思っています。

stageをスキップする方法

停止ではなく、特定条件によっていstageをスキップして次のstageを処理させる方法がわかりませんでした。

まとめ

ジョブの設定画面、Jenkins設定画面とかはそれほど大きく見栄えは変わっていないので、Jenkins1を使っていた人はスムーズに触れるのではないかと思います。
Pipelineスクリプトは非常に便利だと感じました。Jenkinsfileを作っておいてレポジトリに保存すれば、ある意味Jenkinsに状態を持たせなくすることができるので、よりポータビリティが高くなるのではないかと思います。
あとはPipelineのスクリプトで、どこまで出来るかもう少し調べてみたいと思います。