UE5/UE4 では workspace のパスが深すぎるとビルドに失敗するため、できるだけ浅い階層への変更が望ましい。
Windows Pro かつ 2 の選択時に「Run service as local or domain user」を選択している場合は不要。
Ubuntu, Debian 等
$ sudo apt install openjdk-17-jdk $ sudo apt install jenkins
def script_repo= "${GIT_REPOSITORY}/gitsync.git" checkout changelog: false, poll: true, scm: [$class: 'GitSCM', branches: [[name: '*/master']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'script']], userRemoteConfigs: [[url: script_repo]]]
// ローダー def lib= load( "${WORKSPACE}/script/library_code.groovy" ) lib.lib_main()
// library_code.groovy def lib_main() { ~ } return this
外部コード上で直接変数に値を保存しておいて、それを参照する場合は def ではなく this を使う。変数宣言は return this を返す実行コンテキストのローカル変数とみなされるため。
// library_code.groovy def LocalPath= '~' def getLocalPath() { return LocalPath // ← できない } return this
// library_code.groovy this.LocalPath= '~' def getLocalPath() { return LocalPath // ← できる } return this
どうしても def で宣言しておきたい場合は @Field を使う。
// library_code.groovy import groovy.transform.Field @Field def LocalPath= '~' def getLocalPath() { return LocalPath // ← できる } return this
名前付き引数による関数呼び出しは、辞書 (Map) に変換される。 関数宣言時に引数を Map で宣言する。
def message( Map args ) { echo args.url ~ }
message url: ~
引数が省略された場合は null になるので、null 判定でデフォルト引数に置き換える事ができる。
外部スクリプトファイル内で class 定義ができるが、groovy の場合実行するコードコンパイル時に型名が判明していなければならない。 そのため load した script 内ではその class 名を使用することができない。
def lib= load( "LibClass.groovy" ) def obj= new LibClass() // ← エラー、このコードコンパイル時点で LibClass が定義されていないため
// LibClass.groovy class LibClass { ~ } return this
↓ ローダーを用意し、Lib と実行スクリプトに分ける必要あり
def lib= load( "LibClass.groovy" ) load( "main.groovy" )
// main.groovy def obj= new LibClass() // ← 成功
また class 内では jenkins のデフォルト context が無効なので、node, stage, println などの jenkins の基本命令ですら直接実行することができなくなる。 必ず実行中の context を明示的に渡す必要がある。以下の例のように必ず lib. をつける必要あり。
class LibClass { def lib= null def LibClass( lib_ ) { this.lib= lib_ } def steps() { lib.node( 'agent01' ){ lib.stage( 'stage' ){ lib.println( "~" ) } } } }
// main.groovy def obj= new LibClass( this )
また class 名は global な namespace に属するため、class 定義が含まれる script を複数回読み込むと多重定義エラーになる。
特定の Agent 上でジョブを実行したい場合は node() に引数として名前を与える。 ノード名や、Node に割り当てたラベルを指定できる。
node( 'windows' ){ ~ // ラベル 'windows' を与えた Agent 上で実行 } node( 'linux' ){ ~ // ラベル 'linux' を与えた Agent 上で実行 }
ただし node() 命令の中でさらに node() 命令を使った場合、同じ自分自身の場合も executor を消費する。
例えばすでに agent01 上で走っている場合に中でさらに node( 'agent01' ){ ~ } を実行すると、一つの job の実行に2つの executor を消費する。 このとき割当可能な executor がない場合はデッドロックする。 そのため入れ子になった node() 命令を多用する場合は、node の設定で「同時実行数」を多めに設定しておいた方が良い。