Engineer's Way

主にソフトウェア関連について色々書くブログです。

Master - Slave構成のJenkinsでpackage.jsonのversionをジョブ環境変数に設定する方法

  f:id:matsnow:20180319025016j:plain

前置き

現在手がけているElectronベースのプロジェクトでは、Master / Slave構成にしているJenkins環境を使ってCI / CDを回しています。
今までビルド成果物のバージョンはビルドパラメータで手動で指定していましたが、そのあおりを受けてpackage.jsonに書かれているversionが放置気味になっており、ソースコードだけではバージョンがいくつなのかよく分かりませんでした。
そこでpackage.jsonのversionをビルドパラメータにして二重管理をやめようと思い、EnvInject Pluginを使ってみたところ、package.jsonを読み込めずに少しハマりました。
以下はその詳細と解決方法です。

問題

EnvInject Pluginを使うことで、Groovyスクリプトの実行結果をジョブ環境変数に設定することができます。
このGroovyスクリプトの中でpackage.jsonを読み込み、JSONをパースすれば、versionを取得してジョブ環境変数に設定できます。
Jenkins環境が単一ノードで構成されている場合はファイルシステム上のpackage.jsonを読み込めば良いのですが、Master / Slave構成の場合、EnvInject PluginはMasterノードで動作するので、ファイルシステムにpackage.jsonがありません。(package.jsonが存在するのはSlave側)

最初はこれに気づかずに

def json = new File("./package.json").text
new JsonSlurper().parseText(json)

みたいなGroovyスクリプトを書いて「エラーが出るんだけどなんで?」と悩んでいました。

解決方法

ファイルシステムではなく、URLでpackage.jsonを参照することで読み込むことができました。 (例: http://localhost:8080/job/sample/ws/package.json )
URLの /ws/package.json より前の部分は、ジョブ環境変数 JOB_URL から取得します。

また、自分で任意のバージョンを指定することも引き続きできるようにしたかったので、ビルドパラメータも引き続き用意しました。 以下のスクリプト例ではビルドパラメータ specifiedVersion が指定されていればそれを、 指定されていなければ package.jsonから取得した version をジョブ環境変数version として参照できるようにしています。

import groovy.json.JsonSlurper

def specifiedVersion = binding.getVariable("specifiedVersion")
if (specifiedVersion.size() == 0) {
  def fileurl = binding.getVariable("JOB_URL") + "/ws/package.json"
  def inputJSON = new URL(fileurl).getText()
  def parsedJSON = new JsonSlurper().parseText(inputJSON)
  return [version: parsedJSON.version]
} else {
  return [version: specifiedVersion]
}

f:id:matsnow:20180731025722p:plain

参照方法

シンプルに

echo $version

でOKです。

注意点

  • ビルドパラメータはスクリプトでは上書きできません。 上の例でビルドパラメータをspecifiedVersionとしているのはそのためです。
  • $JOB_URL/ws/package.json にGETした時、403が返ってくる可能性があります。その場合はJenkinsのグローバル設定でアクセス権を見直す必要があります。

Jenkinsの関連記事

matsnow.hatenablog.com matsnow.hatenablog.com