目次
Jenkins
Windows
(1) jenkins install
- OpenJDK 17 or 11 install
- jenkins で使用するなら zip 版を適当なフォルダに展開するだけで OK
- jenkins install
- https://www.jenkins.io からダウンロードしてインストーラーを起動
- jenkins install path の設定 (default で OK)
- user の選択
- “Run service as LocalSystem (not recommended)”
- Windows Home の場合はこちら
- “Run service as local or domain user:”
- 任意のユーザーを入力可能。事前にサービスとしてログオンの設定が必要
- Windows Pro のみ: Start Menu から ローカルセキュリティポリシー を起動し、ローカルポリシー → ユーザー権利の割当 → サービスとしてログオン にユーザーを追加しておく
- port 設定
- 任意。デフォルトだと 8080
- OpenJDK のインストールパス選択
- 1 でダウンロード&展開したフォルダを入力
- install
- browser で initialAdminPassword を入力
- ユーザー作成
- おすすめ plugin のインストール
- またはカスタムで plugin を選択&不要なもののチェクを外す
(2) 必要な場合のみ Jenkins HOME (workspace path) の変更
UE5/UE4 では workspace のパスが深すぎるとビルドに失敗するため、できるだけ浅い階層への変更が望ましい。
- コンピューターの管理 → サービスとアプリケーション → サービス → Jenkins 停止
- インストールフォルダ内の jenkins.xml を編集
- JENKINS_HOME の value=“%LocalAppData%\Jenkins\.jenkins” を変更する。
- 例: value=“C:\Jenkins”
- 元の JENKINS_HOME のフォルダの内容を新しいフォルダに全部コピー
- 例: %LocalAppData%\Jenkins\.jenkis の内容を C:\Jenkins にコピー
- コンピューターの管理 → サービスとアプリケーション → サービス → Jenkins 開始
- 正しく動作することが確認できたら、元の JENKINS_HOME の内容を削除
- Jenkins の管理 → システムの設定 → ホームディレクトリ で確認可能
(3) Windows 11/10 Home の場合、User の変更
Windows Pro かつ 2 の選択時に「Run service as local or domain user」を選択している場合は不要。
- 先に Jenkins HOME を別の絶対パスで指定したフォルダに移動しておく
- コンピューターの管理 → サービスとアプリケーション → サービス
- Jenkins → プロパティ → ログオンタブを開いて、アカウントを入力
(4) その他設定
- Plugin
- Jenkins の管理 → プラグインの管理
- P4 Plugin, Slack Notification, Discord Notifier など
- 利用可能タブで検索して必要なものにチェックし Install without restart
- 全部インストールしたらリスタート
- 変数
- Jenkins の管理 → システムの設定
- グローバルプロパティの環境変数に、共通で使う設定を登録しておく
- git 名の変更
- Jenkins の管理 → Global Tool Configuration
- GIt の「Git実行形式へのパス」を “git.exe” から “git” のみに変更
- これをしておかないと、Windows Master から Linux Agent を呼び出した場合に GitSCM の checkout が失敗する
- Agent
- Jenkins の管理 → ノードの管理
- master (controller) も使う場合、master → 設定 → ラベルに任意の名前を設定 (controller, agent01, windows など)
- 新規ノード作成 → ノード名設定、Permanent Agent On → OK
- 必要に応じて追加
- Linux Agent は ssh 設定 + openjdk だけで利用できる。
Linux
直接 install する場合
Ubuntu, Debian 等
- install
$ sudo apt install openjdk-17-jdk $ sudo apt install jenkins
- ブラウザで http://localhsot:8080/ を開いてセットアップ
docker を使う場合
- mkdir jenkins
- cd jenkins
- mkdir jenkins_home
- vi docker-compose.yml
- docker compose pull
- docker compose up -d
Linux agent の作成
- Windows の Jenkins の Agent として使用する場合は git の設定に注意
- デフォルトで git.exe が登録されているため Linux でエラーになる
- Jenkins の管理 → Global Tool Configuration
- GIt の「Git実行形式へのパス」を “git.exe” から “git” のみに変更
- Linux 側で sudo apt install openjdk-17-jre
- Linux 側で ssh 設定
- sudo apt install ssh
- ssh-keygen -t ed25519 -C $HOST
- sudo vi /etc/ssh/sshd_config (→ PasswordAuthentication no)
- vi ~/.ssh/authorized_keys (→ pubkey 追加)
- Jenkins 側
- Credentials → SSH User name and Secret Key
- global seculity → Git Host Key Verification Configuration → Accept first connection
- Node 追加
Pipeline の設定
- 新規ジョブ作成 → パイプライン
SCM ポーリング
- Pipeline script で SCM ポーリングを行う場合は、一度スクリプトを走らせておく必要あり。
- 以前実行した script 中に checkout コマンド (poll:true) ある場合に、そのリポジトリがポーリング対象になる。
- スクリプトコードを登録しただけではポーリングが行われない。
- リポジトリは複数存在していても良い。
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]]]
外部コードの読み込み
- load コマンドを使って、他のファイルを読み込むことができる。
- 読み込まれる側のスクリプトは、最後に “return this” が必要。
- jenkins 上の設定は最小限のコード (ローダーのみ) にしておいて、続きはリポジトリ内のスクリプトを読み込んで実行することができる。
// ローダー 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 定義
外部スクリプトファイル内で 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 の指定
特定の Agent 上でジョブを実行したい場合は node() に引数として名前を与える。 ノード名や、Node に割り当てたラベルを指定できる。
node( 'windows' ){ ~ // ラベル 'windows' を与えた Agent 上で実行 } node( 'linux' ){ ~ // ラベル 'linux' を与えた Agent 上で実行 }
ただし node() 命令の中でさらに node() 命令を使った場合、同じ自分自身の場合も executor を消費する。
例えばすでに agent01 上で走っている場合に中でさらに node( 'agent01' ){ ~ } を実行すると、一つの job の実行に2つの executor を消費する。 このとき割当可能な executor がない場合はデッドロックする。 そのため入れ子になった node() 命令を多用する場合は、node の設定で「同時実行数」を多めに設定しておいた方が良い。