1
0

More than 1 year has passed since last update.

Jenkins覚書

Last updated at Posted at 2022-09-15

概要

Jenkins-Pipelineについての覚書レベルのものを羅列。
嵩張りそうなら個別のページに切り出す。

個別ページに切り出した項目

pipeline中に使える変数

${jenkinsmachineのURL}/pipeline-syntax/globalsで確認できる。

Jenkinsfileにparametersを足した時などに一度リロードさせたい

1度実行しないとparametersは反映されない。
そのため、以下のような下準備を行っておくとよいと思われる。

pipeline {
  parameters {
    booleanParam(name: 'RELOAD_PIPELINE', defaultValue: false, description: 'Job定義ファイルを再読み込みして即終了(ABORT)する')
  }

  stages {
    stage('Reload') {
      when { expression { params.RELOAD_PIPELINE } }
      steps { script {
        echo 'Reload'
        currentBuild.result = 'ABORTED'
        error('Reload jenkins files.')
      } }
    }
  }
}

currentBuild.result = 'ABORTED'しておくことでpost { failure { ... } }の処理が呼ばれないので便利!

マスターマシンとビルド(スレーブ)マシンが違う場合における処理のShared Libraries(モジュール)化

基本は↓を参照。

ただ、マスターマシンとビルド(スレーブ)マシンが違う場合には上記の処理ではうまく読み込めなかった。(詳しい方アドバイスをいただきたいです)

色々試した結果、以下のようにするとスレーブマシンでもモジュールを読み込めたので記載する。

  1. 任意のレポジトリのトップレベルディレクトリvarsという名前のディレクトリを作成
  2. vars内に${some_name}.groovyというgroovyスクリプトを置く
    • 中身はdef call() {から始まるcall関数(パラメータがあってもよい)があれば関数やクラスの宣言があっても問題ない模様
      • e.g.
        TriggerJob.groovy
        def call(jobName) {
            build(
              job: "${jobName}",
              wait: false,
              parameters: []
            )
        }
        
    • groovyではあるが、Jenkins-ScriptなのでwithEnvshwithCredentialsなどstepsに記述できるものは何でも記述可能である模様(未検証)
  3. 呼び出し元のJob内でscript { library(identifier: 'lib@master', retriever: legacySCM(scm)) }を呼び出す。
    • e.g.stage('Import') { steps { script { library(identifier: 'lib@master', retriever: legacySCM(scm)) } } }
      • identifierは何でもいい模様
      • retrieverはlegacySCM(scm)以外だとうまくいかなかった。(要検証)
  4. 呼び出したいstepsでsome_name()と書くだけで呼び出しが可能
    • e.g.stage("trigger_job") { steps { TriggerJob("other_job_name") }

groovy変数をsh内で参照する方法

groovy変数をsh内で使用するには以下の方法がある。

  1. sh "...${variable}..." のように"の中に書く
  2. sh '...' + variable + '...'sh '''...''' + variable + '''...'''のように一度文字列を終了させて+で連結させる。
  3. 環境変数化
    1. withEnvブロックを使う
      • e.g. withEnv(["VARIABLE=" + variable]) { sh '..."${variable}"...' }
      • 基本はこれを使用すれば良さそう
    2. environmentブロックを使う
      • e.g. stage(...) { environment { VARIABLE = "${variable}" } steps {...} }
      • groovyとしてわざわざ使う機会はないはず?
    3. env.NAMEに代入する
      • e.g. env.VARIABLE = variable
      • 既に定義済みの環境変数を上書きすることはできない点に注意

変更ログを取得する

変更ログの取得方法は2通りあり、APIを使用する方法とgroovy変数を参照する方法である。

API

以下のURLにアクセスすればよい。

${BUILD_URL}api/xml?xpath=//changeSet//comment/text()&wrapper=changes

解説すると以下のような感じ。

  • api/xmlはXML形式で結果を返すことを指す。
  • xpath=//changeSet//comment/text()
    • xpathはXPathというコマンド?(未調査)と同じ挙動をさせるらしい。
    • //はいずれかの階層とのこと。changeSetはworkflowRun/changeSetでもアクセスできるが、//と書くことにより、任意の階層にマッチできる。
      • よくあるパス指定での/**/みたいなものだと思っている。(未検証)
    • text()//commentでも取ってこれるが、text形式のものだけ抽出する(未調査)ことができるので楽っぽい。
    • xpath=//comment/text()だけでも要件は満たせたが、changeSetも指定した方が厳密な気がしたので採用している。
  • wrapper=changesは最上位のタグをchangesにする?(未調査)
    • とりあえず必要なので付けている。
    • sedあたりにpipeで渡してあげれば良さそう。

注意点

  • ユーザー認証などがある場合はAPI-Tokenの用意などが必要。

groovy変数(currentBuild.changeSets)

以下のコードで動作した。

def getChangeMessages() {
    def messages = ""
    for (entries in currentBuild.changeSets)
    {
        for (entry in entries.items)
        {
            messages += "${entry.msg}\n"
        }
    }
    return messages
}

groovy変数名について

未検証

以下のような機能を作成した際、

def getChanges() {
    def changes = ""
    for (entries in currentBuild.changeSets)
    {
        for (entry in entries)
        {
            changes += "${entry.msg}\n"
        }
    }
    return chages
}

以下のようなエラーが出て困ったことがある。

groovy.lang.MissingPropertyException: No such property: chages for class: groovy.lang.Binding
Possible solutions: class
	at groovy.lang.Binding.getVariable(Binding.java:63)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:270)
	at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:291)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:295)
	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
	at MyModule.getChanges(MyModule.groovy:11)
	at MyModule.call(MyModule.groovy:16)

散々試した結果、changesという変数名をmessagesに変更したら大丈夫だった。
MissingPropertyExceptionを見かけたら名前を変えてみるといいのかも?

API呼び出し結果を検証する

Jenkinsというよりはshの挙動なのだが、CIに関わってくるので記載。

curl -I ${url}でhttp_codeを取得できるのだが、これはGETにしか使用できない。
そのため、POSTで使用するには以下のようにする必要がある。(GETにも応用はできるはず)

curl -w '%{http_code}' -o /dev/null ${post_parameters} ${url}

だが、これだとレスポンスの内容が取得できないので以下のようにする必要がある。
-wで指定する内容にcontentの内容が含まれていない点に注意。

set -e
response=$(curl -w '\n%{http_code}' ${post_parameters} ${url})
http_code=$(echo "${response}" | tail -n1) # "でエスケープしないと改行が変になるため正常に取得できない
test ${http_code} = "200" # 200以外ならエラー終了

レスポンスの内容も出したいなら↓のようにする。

echo "${response}" | head -n -1

ダウンロード進捗表示

curl ... 2>/dev/nullしなくてもcurl -s ...で消せる。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0