Jenkins 個人的FAQ?

# はじめに

この記事は曲りなりにも新卒から自動化周りに関わっている僕がこうしたら良かったなやこうしたからよかったというのをFAQ形式にまとめた記事です。

半分自分のため、半分誰かのためです。

### 注意

以下の記述には全てプロジェクトやチームによる。
という但し書きが付きます。

また、あくまでも自分はこうしたら良かったなので、人によって考えがあると思います。
もし自分はこうしているがあればコメントいただけると嬉しいです。

# ジョブの名前やレイアウトなどについて

## ジョブの命名規則は？

A.
1. 単語を「-」で区切る
2. 日本語を使っても良い
3. 単語の頭文字は大文字 (優先度低い)

 単語を「-」で区切る、はブラウザ(Chrome)で単語をダブルクリックすると単語が選択された状態になるので、以下のように名前の似ているジョブに飛ぶ時に便利だからです。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77177/ab5408bc-7330-baf3-fa9c-2e5deea6162e.png)

日本語を使っても良い、は主に非エンジニア向けジョブの場合に英語に拒否感がある方もいるということが大きな理由。
難しい英語使うよりは日本語でいいじゃんという理由もあります。

単語の頭文字は大文字、は個人的にこちらのほうが見やすいだけなので小文字でもOK。

## フォルダ vs ビュー どちらを使うべき？

A.
使い分けろ、対立する概念ではない
最初に考えるのはフォルダ分け

まず、フォルダ分けを考えてください。
ジョブは必ず1つのフォルダにしか存在できません。

その後、(リスト)ビューで分けたほうがいいやビューに集約したいと言う時にビューを使う。(例えば本番系だけ集約したビューがほしいなど)
特に、フォルダの階層が違っていてもそのフォルダ以下のジョブであれば、設定の「サブフォルダーを表示」にチェックを入れればビューの選択肢に入れられるので活用する。

また、正規表現を活用すれば新しく出来たジョブも自動で追加してくれます。

## どういうふうにフォルダ分けをする？

注目するべきオブジェクトでフォルダ分けをする。例としては、

1. 実行バイナリ → 作成ジョブ アップロードジョブ　
1. テスト → 単体テスト 結合テスト

などなど、[オブジェクト指向UI](https://nijibox.jp/blog/ooui/)と同じような区分けの仕方でいいと思っている。

更にタスク(例えば本番用)などで区分けしたい場合はビューを使うといい感じがする

## ジョブをいい感じに並べ替えたいんだけど…

自分もどうすればいいのかわからない…
ただ、並び順は辞書順なのでジョブ名の頭に「1. 2.」のような数字振っておくと一応並べ替えてくれる。

# 設定について

## pipelineで共通な処理をライブラリ化したい。

A.

設定に「Global Pipeline Libraries」という項目があるのでそこで設定可能
これは多分必須技術なので、ちゃんと理解したほうがいいです。

[Extending with Shared Libraries](https://www.jenkins.io/doc/book/pipeline/shared-libraries/)

## Jenkins複数運用しているけれどそれぞれひと目で分かるようにしたい。

A.
[Simple Theme Plugin](https://plugins.jenkins.io/simple-theme-plugin/) 使ってCSS適用するといい

適用するテーマは以下が便利（2022年現在 JenkinsたまにUI変わるので最適なテンプレート変わるかも）
https://tobix.github.io/jenkins-neo2-theme
https://github.com/alefnode/jenkins-themes

## ジョブの設定を一気に変えたい(ログローテーションなど)

A. 
[Configuration Slicing Plugin](https://wiki.jenkins.io/JENKINS/Configuration-Slicing-Plugin.html)を使用する

## Jenkinsの設定バックアップ取りたい

A.
いくつか方法はあるが[Jenkinsのバックアップを簡単にデイリーでとる ついでにバージョン管理する](https://qiita.com/Marimoiro/items/84907f657937ce02e463)が未だに一番簡単だと思う（自分の記事）

# コントローラーとエージェント (マスターとスレーブ)

名称変更に関しては[【CI奮闘記】第5章：コントローラー？エグゼキューター？エージェント？](https://cloudbees.techmatrix.jp/blog/struggle-story-about-ci-5/)が詳しい

ちなみにcontorollerのノードへのagent指定は以下の様にする

```groovy
    agent { label 'built-in' }
```

## コントローラーにジョブの実際の作業をさせるのはアリ？ナシ？

A.
できれば避けたい。1台しかPCがない場合でもエージェントのプロセスを同じPC内で起動させたほうがいい。

1台でも分離しておきたい、理由としては、

* ワークスペースと設定が一緒になるとトラブル時調べるの少し面倒くさい
* もう一台使おうやエージェント増やそうとなった時に引っ越しが簡単
* ユーザーや権限をコントローラーの実行ユーザーとは切り離したいことが結構ある

## エージェントやコントローラーを仮想化する？

A.
プロジェクトと相談

最近のコンパイラは（言語によるが）環境の依存が少ないので、そこまで強固に共通の環境がほしいかと言われるとそこまでしなくても大丈夫な場合も多い。（とくにC#は環境依存あんまりなくていいぞ）

そうなると、そこまで仮想化したりするメリットないかも。
ただし、プロジェクトの内容による。

## エージェントの初期設定はどうやって行う？

A.
プロジェクトと相談。
とりあえず何らかの形で共通化出来ていてコード化出来ているとgood!

Ansibleでもdockerでも初期設定スクリプトでもプロジェクトにあったものを使ってね。
chocolateyとかbrewとかaptとかで初期設定スクリプト書くだけで十分なことは結構あるよ。

## とあるジョブだけいつも優先度最高にしたい。がエージェントマシンは同じにしたい。

A.
同じマシンにエージェント2つインストールして片方をそのジョブ専用にするのが楽

この方法は他にも、別のキューで管理したいジョブがある時に便利。
色々プラグインあるけど、そこまで多い要求ではないのでエージェント2つがシンプルでお勧め

# ジョブについて

## パイプライン vs フリースタイル

A. 
基本パイプライン。フリースタイルは簡単なシェルで完結するやつとか。

フリースタイルバージョン管理しにくいし、if挟むのだって大変だし…あんまりおすすめしなーい

## 複数のジョブでワークスペース共有したい

A.
とてもおすすめしない

複数のジョブでワークスペースを共有するということは複数のジョブでワークスペースを共有するということであり
いろいろな問題が発生する要因になりやすいため、可能なら（容量が問題であれば）SSD増設とかで対応した方がいい。
増設したSSDは別エージェントとして扱うといい。

## パラメータをたくさん持ったジョブを作る vs パラメータが少しずつ違うジョブを複数作る

A.
パラメータが少しずつ違うジョブを複数作る方がおすすめ
今はJenkinsfileの変数をうまく使えばコピペする必要はあんまりない。

また、パラメータが特定の組み合わせでのみ失敗するとその調査がとてもとても面倒くさくなるので、避けたほうがいい。
パラメータをたくさん持ったジョブを作るというのは複数のジョブでワークスペース共有するというのと似た問題が発生しやすい


以下全部Pipelineの話

## stageの区切り方

A.
ここからリトライしたいことあるかも…が基準でいいかも
時間がかかる部分（ビルドとかデプロイとかね）でも区切るといいかも
逆にそこから再開してもビルドが壊れるような場所で区切るのは避ける。

Restart from Stage　というあるステージからリプレイするという機能があるのでうまく利用できる分割するとお得。

なお、設定>シャットダウンの準備を入れるとステージの切れ目で止まるので、ここからステージの切れ目から再開されることはいつでもあると思っておいたほうがいいです

## シェル言語って何にする？

A.
何でもいい
Windowsで実行するならPowerShellもお勧め

WindowsはPowerShellがプリコンパイルで追加しなくていいしZipに固めるくらいならデフォルトで入っているので結構おすすめ。
ただし、エラー処理が面倒くさいのでそこに気をつける。

sh系でやる場合はシェル芸になって自分しか読めない！というのを避けたい。
できるだけ何やっているかわかるようにしておこう。
（あとawkとかwgetとかビルドインされてなかったりするから注意）

### 成果物大きいからあんまり保存したくないけれど、ログは長期間残したい

A.
古いビルドの破棄の高度な設定から設定できます

## Jenkinsfile周り

### Jenkinsfileはプロジェクトコードと同じリポジトリに保管する？それとも違う場所？

A.
どっちでもいい

ただし、プロジェクト自体が大きめ(Unityなど)だとgit checkoutの都合など考えて別リポジトリにしたほうが便利。

ちなみにJenkinsfileにも.groovyってつけたほうがgithub上のシンタックスハイライト効いていいよ(例:deploy.groovyなど)。

### Jenkinsfile共通化したいからgitのリポジトリのurlをjenkinsfileにハードコードしたくない…
A.
設定の環境変数に入れてそれを参照するといい。

ちなみにリポジトリの引っ越しなどでurlが変わるときも一括で変えられたりするのでわりかしおすすめ。

### jsonとかyamlとかproperties パースしたい

A．
[Pipeline Utility Steps](https://www.jenkins.io/doc/pipeline/steps/pipeline-utility-steps/)入れとけ

ちなみにどの設定ファイル形式を使えばいいか悩んだ場合は若干だけどお勧めはproperties 理由はjavaの形式だから。

### ファイルの存在チェックしたい

A．
[Pipeline Utility Steps](https://www.jenkins.io/doc/pipeline/steps/pipeline-utility-steps/)入れとけ


### とりあえず便利機能ほしい

A．
[Pipeline Utility Steps](https://www.jenkins.io/doc/pipeline/steps/pipeline-utility-steps/)入れとけ

### タイムスタンプ入れたい

A.
むしろ全部のジョブに入れておくことを推奨
Pipeline Syntax: Directive Generator のoptionsから生成できるけど以下のコードを入れると出せる。

```groovy
options {
  timestamps
}
```

### Jenkinsのジョブの設定とかそういうの弄くりたい。

A. 
この辺のAPI使おうと思えば使える(In-process Script Approvalの設定が必要)



[RunWrapper](https://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html)
```groovy:現在のビルドを取得
currentBuild.rawBuild.project 
```

[Run (Jenkins core 2.336 API)](https://javadoc.jenkins-ci.org/hudson/model/Run.html)
```groovy:現在のビルドの生データを取得
def raw = currentBuild.rawBuild
```

[Job (Jenkins core 2.336 API)](https://javadoc.jenkins.io/hudson/model/Job.html)
```groovy:自分自身のJobオブジェクトを取得
def project = currentBuild.rawBuild.project 
```

Jenkinsのジョブ一覧のリスト化 (ここから当然検索して特定のジョブを操作するとかも可能)
[Groovy to list all jobs](https://support.cloudbees.com/hc/en-us/articles/226941767-Groovy-to-list-all-jobs)

[Jenkinsのグローバル環境変数をジョブから変更する](https://qiita.com/Marimoiro/items/a68c511a7af891a368e2)

### なんかこんなことしたいんだけどJavaのライブラリに〇〇ってクラスあったから使っていい？

A．
まずpipelineのプラグインで同じことできそうなやつ探したほうがいい。
Jenkins特有の問題解消してくれてたりする。

どうしてものときは…諦めて使えばいいんじゃないかな？


### プラグイン信用できない！自分で書く！

A.
その信用できないプラグインDL数千以上あって少なくともあなたの書いたコードより信用できます。
なのでプラグインで書けるところは書きましょう。

### groovyわかんない！全部シェルにする！

A.
あなたが書いた読みにくいシェルを誰が保守するんですか？
jenkins pipelineの共通言語はgroovyです。
シェルはあくまで必要な時に使おうね。

## その他

### Jenkinsと他のCIツールの違い

A.
プロジェクトで好きなの選んどけばいいけど、強いて言うならインストール型かサービス型かはポイントになると思う。
あと個人的にはJenkinsはそこそこ非エンジニアフレンドリーだとはおもう。

### なんかわかんないけどこういう時どうするの？

[Jenkins Handbook](https://www.jenkins.io/doc/book/)