jenkins学習メモ2 サンプルジョブ作成～実行

## はじめに
船井総研デジタルのoswです。業務でjenkinsに触れることになったので学習記録を残します。参考になる方がいらっしゃれば幸いです。

## このシリーズのゴール
下記をゴールとします。
- 閉じたLAN環境にあるマシンにjenkins環境を構築（別マシンからjenkinsにアクセス）
- 手動でジョブを起動し、githubリポジトリをクローン / 単体テストを走らせる

## 学習環境
- Windows 11 (WSL2 Ubuntu)
- Rocky Linux 9.1
- jenkins 2.375.3

## 前回の学習内容
インストール～ログインして環境構築まで学習しました。

https://qiita.com/fsd-osw/items/446d44855719048d5948
            
## ジョブの作成
### ジョブとは
jenkins上で行う処理の単位。実行したい一連の処理をジョブとして定義し、特定のタイミング（プッシュを検知など）で動くように設定します。複数のジョブを定義、連携させる事でCI/CDを実現するようです。

また、ジョブを作成する粒度ですが、基本的には1つのジョブでがっつり処理させるより複数のジョブを定義し、それらを連携させるなど再利用できる粒度で作るのが良いようです。（ジョブから別のジョブを呼び出すことも可能）

### ジョブの作成方法
[ダッシュボード]画面の左ペインにある[新規ジョブ作成]を押下すると作成画面に遷移します。ジョブの作成方法として押さえておきたい方法として下記の2つがあるようです。

いずれの方法もジョブ設定時にビルドパラメータを設定するとジョブにパラメータを渡すことができます。また、詳細は後述するとしてパイプラインでジョブを作成するのが多いようです。

1. フリースタイル・プロジェクトのビルド
1. パイプライン

![ジョブ作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/eacbd51f-a3d9-6ddc-5029-af4b0d86dcbd.png)

### フリースタイル・プロジェクトのビルド
まずはフリースタイルジョブの作成を行います。ジョブ作成画面でジョブ名を入力、「フリースタイル・プロジェクトのビルド」を選択肢、「OK」ボタンを押下します。今回作成するジョブは「freestyle-job」としました。

![フリースタイルジョブ作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/eba16694-1f65-ab2d-bb74-ab44f0ee8056.png)

#### フリースタイルジョブの設定
下記を入力し、ページ下部の「保存」を押下します。パラメータとして"test arg"という文字列を設定してみました。
- General
    -  説明
        -  Jenkins学習用ジョブ - フリースタイル
    -  ビルドのパラメータ化（文字列）[^1]
        -  名前：ARG
        -  デフォルト値：test arg
        -  説明：ジョブに渡されるパラメータ
-  Build Steps
    -  シェルの実行
        -  echo $ARG
[^1]: 文字列と似たようなもので「テキスト」がありますが、こちらは複数行設定可能なようです。

#### ジョブの実行
設定を保存するとジョブの詳細画面に遷移します。[パラメータ付きビルド] - [ビルド][^2]を押下するとジョブが実行されます。

この時、ジョブの設定時に設定していたパラメータが表示されていますが、変更することも出来ます。ここで設定したパラメータはその「実行したジョブ」だけに適用され、ジョブの設定自体は変更されません。

[^2]: ジョブの実行をビルドと表現しているようです。

![フリースタイルジョブのパラメータ付きビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/9ddfd624-f074-7362-329b-502e63ce0d2a.png)

#### ジョブの実行結果を確認
ジョブの詳細画面 左下のビルド履歴を押下すると対象の実行結果を確認することが出来ます。この時、結果が緑なら正常終了、赤なら異常終了となります。

![フリースタイルジョブのビルド履歴.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/0c68f3bb-486b-6f28-ec4b-7f46374d8fe9.png)

![フリースタイルジョブの実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/5171ba81-3e82-5052-07ec-9a8f33165c98.png)


また、左ペインから「コンソール出力」を選択すると、ジョブが出力した内容を確認することができます。渡したパラメータ、「ARG」の中身が出力されています。

![フリースタイルジョブのコンソール出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/bc667e83-3acc-cb95-e769-b47f55678189.png)

#### ジョブの設定を変更する
ジョブの設定は、[ジョブ詳細画面] - [設定]で変更することができます。

![フリースタイルジョブの設定変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/9435312f-f250-053c-c4fc-c9575073ddd9.png)


### パイプライン
次にパイプラインでジョブを作成してみます。ジョブ名は「pipeline-job」としました。
![パイプライン作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/dc47f12d-b7d1-da01-18d7-2f4fdde61f08.png)

#### パイプラインジョブの設定
フリースタイル同様、下記を入力してページ下部の「保存」を押下します。パラメータは複数行の文字列を設定する「テキスト」で渡してみました。処理の記述ですが、パイプラインはフリースタイルと違って「pipeline script」に処理の内容を記述し、groovyが記述が可能のようです。

本来、groovyはscript{}内に記述する必要があるようですが、pipeline全体がscript{}ブロックに包含されているため、script{}を記述せずにそのまま記述することも可能です。ただ、script{}内に記述すると変数のスコープがそのブロック内で閉じたものになるため、スコープを大きくしないためにもscript{}ブロック内に記述する方が良さそうです。

- General
    -  説明
        -  Jenkins学習用ジョブ - パイプライン
    -  ビルドのパラメータ化（テキスト）[^1]
        -  名前：ARG
        -  デフォルト値：
            ```
            hoge
            hoge
            ```
        -  説明：ジョブに渡されるパラメータ（複数行）
- Pipeline script
    - Script
        ```bash
        // 定義したパラメータを取得
        def arg = ARG
        
        pipeline {
            // ビルドの実行環境。登録されていれば別のマシンで動くagentにジョブを実行させる場合もある
            agent any
        
            // 処理を「ステージ」として段階的に定義する。ビルド結果はステージごとに視覚化される
            stages {

                // ステージ: build として定義
                stage('build') {
                    // ステージごとに実施する処理をsteps内に定義。stepsは1つだけ
                    steps {
                        print 'ビルドを開始します'
                        script {
                            def bar = "bar"
                        }
                        print ARG
                        print "${arg}"
                        // print "${bar}" barはスコープ外なので参照できない
                        print 'ビルドが正常終了しました'
                    }
                }

                // ステージ: test として定義        
                stage('test') {
                    // ステージごとに実施する処理をsteps内に定義。stepsは1つだけ
                    steps {
                        print 'テストを開始します'
                        print 'テストが正常終了しました'
                    }
                }
            }
        }
        ```

Pipeline scriptは下記記事でまとめてくださっています。

https://qiita.com/miyasakura_/items/9d9a8873c333cb9e9f43

また、Pipeline scriptは用途に合わせたコードジェネレータが用意されているようで、1から構文を覚える必要はなさそうです。下記画像のPipeline scriptを記述する画面にある「Pipeline Syntax」を押下するとコードジェネレータの画面へ遷移します。

![パイプラインシンタックス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/870903d5-fa8c-1128-9803-ac72a45757ba.png)

左ペインで生成したいコードに合わせたカテゴリを選択し、[Sample Directive]を選択します。あとはパラメータの要素を指定し、[Generate Declarative Directive]を押下するとコードを生成してくれます。

![サンプルシンタックス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/2a31e547-f615-32ef-b732-56a68fc9451b.png)


#### ジョブの実行
ジョブの実行方法はフリースタイルと同じ方法で可能です。詳細画面の[パラメータ付きビルド] - [ビルド]で実行可能です。
![パイプラインジョブのパラメータ付きビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/55cdc67d-2bc1-3736-ba04-a4eb68422d26.png)

#### ジョブの実行結果を確認
フリースタイルと同様です。詳細画面のビルド履歴から対象を選択します。フリースタイルと違い、pipeline scriptで定義した「ステージ単位」で結果が視覚化されます。

今回は「build」、「test」の2つを定義したのでそれらが見えています。フリースタイルではこのように各処理ごとに結果を視覚化することはできず、パイプラインと同じことをしようとするとフリースタイルジョブをステージと同じ数だけ定義し、それらを実行する前後関係を設定した上で実行すると同じことはできそうです。

ですが、結果が一目でわかるためパイプラインの方が好まれるようです。

![パイプラインジョブのビルド履歴.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/5ff00141-425a-73c9-7ef7-445f481e0cb7.png)

#### ジョブの設定を変更する
フリースタイルと同様です。[ジョブ詳細画面] - [設定]で変更することができます。
![パイプラインジョブの設定変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/d8e981a2-49b8-9397-3353-6103741ec0d0.png)

#### jenkinsfile
パイプラインでジョブを作成する場合、予め定義したPipeline script（これをjenkinsfileと呼ぶようです）を用意しておき、それを読み込むことでもジョブ定義ができるようです。

ファイルである以上gitで版管理が可能です。そのメリットを活かし、実務的にはリモートリポジトリで管理しているjenkinsfileをパイプラインジョブで読み込ませる方がメジャーかも知れません。

#### 補足
pipeline scriptを書く際、UIに直接書くのではなくVSCodeで書くことをおすすめします。拡張機能`Jenkinsfile Support`を入れればスニペット、シンタックスハイライト機能などがあり、非常に便利です。

### フリースタイルでパイプラインっぽくしてみる
パイプラインジョブで実施した「ビルド」、「テスト」ステージの内容をフリースタイルでやってみます。

#### 事前準備
フリースタイルジョブを2つ定義します。（今まで作成したジョブは削除しています）
![作成するジョブ一蘭.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/5cd73a9e-48a4-328a-ca10-4eadbadf0068.png)

作成するフリースタイルジョブは次のように設定します。testジョブ側に「他プロジェクトの後にビルド」を設定することでbuildジョブの後に実行する、前後関係を設定することができます。
1. freestyle-build-job
    1. Build Steps - シェルの実行 - echo "build"
1. freestyle-test-job
    1. ビルド・トリガ - 他プロジェクトの後にビルド - freestyle-build-job
    1. Build Steps - シェルの実行 - echo "test"
![他のプロジェクトの後にビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/65dee190-d9a1-441f-6a4c-0a7507f5ea73.png)

#### ジョブの実行
freestyle-test-jobを実行するとそれが単独で実行されるだけなので、freestyle-build-jobの方を実行します。

#### 実行結果
ジョブの前後関係が設定されていると最初に実行されるジョブ側からは後に実行されるジョブが「下流プロジェクト」として見えるようになります。
![上流プロジェクトの実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/7908163d-2d5b-e8eb-01c9-8e1e87c05eba.png)

後に実行されるジョブからは最初に実行されるジョブが「上流プロジェクト」として見えるようになります。
![下流プロジェクトの実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/a619fe2c-fcf6-478c-d341-e65309fba229.png)

パイプラインの方が結果が視認しやすいことがよくわかります。

## おわりに
pipeline scriptの構文やgroovyなどは最低限覚えないといけないので、そういう意味で若干学習コストは高いかと思います。

ただ、環境設定とジョブの作成方法自体はシンプルですぐに覚えることが出来そうなので、使いながらその都度覚えていくだけでも十分かもしれません。

コードジェネレータが心強い。。