Jenkinsfileの書き方まとめ

# はじめに
本記事では、オープンソースの自動CIツールである [Jenkins](https://www.jenkins.io/) の設定ファイルである Jenkinsfileの書き方について記載する。
JenkinsそのものやCIについての説明は割愛する。

# Jenkinsfileとは？
Jenkinsの処理を単一のスクリプトファイルに記述したもの。
ただし、パイプラインという種類のJenkinsジョブでしか使えないという条件がある。

## フリースタイルとパイプライン
通常Jenkinsのジョブを作成する際は「フリースタイル」がデフォルトとなっているが、「パイプライン」と言う種類を選択することができる。
「パイプライン」を選択すると、Jenkinsfileに記述した処理を実行することができる。
![スクリーンショット 2023-11-29 11.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726845/7c9545d5-90d2-1b75-6f89-ee80ff354d0f.png)

### 長所と短所
フリースタイルの場合はWeb UI上から種々の設定をすることになる。そのため予備知識がなくても簡単に設定をすることができる。しかし変更履歴が残らないため、バージョン管理には不向きである。パイプラインの場合はJenkinsfileの構文を勉強する必要があるが、git等で変更履歴を追うことができる。
また、フリースタイルの方がウェブに転がっている情報は多いため、そういう意味でも初心者向け。

## Jenkinsfileの種類
Jenkinsfileにはdelarativeとscriptedの2種類がある。declarativeの方が新しく、機能的にリッチである。両者は構文が微妙に違うため、注意が必要。ウェブにある情報も多くがdeclarativeなので、基本的にはこちらが推奨。

# Jenkinsfileの使い方
構文に従ってCI時に実行したい処理を記述し、それをgitリポジトリに入れておくだけで自動で処理を実行する事ができる。
やることとしては、Jenkinsfileというファイル名のテキストファイルを作り、ジョブ作成時にJenkinsfileのパスを指定するのみ。この手順の詳細や、Gitlab,Githubとの連携やCIトリガーの設定等はウェブ上に豊富に記事があるためこの記事では割愛する。

## Jenkinsfileの構文
Jenkinsfileでは、CIの各作業を`stage`という作業単位に分割して記述する。このstageをいくつか並べてパイプラインにするのがJenkinsfileの基本的な書き方である。なので、`stages{}`というコンポーネント内に`stage`を並べるだけで最低限動くJenkinsfileが完成する。

### pipelineとagent
Jenkinsfileの最上流のコンポーネントは`pipeline`である必要がある。
pipelineの下には、まずagentを定義し、次にstagesを書いてその中にCIの作業内容を記述することになる。

```
pipeline{
    agent any
    stages{
        CIの作業内容
    }
}
```
agentというのは文字通りJenkinsfileを実行するagentのことで、様々なオプションから選択することができる。
基本はanyにしておいて困ることはないだろうが、便利な機能が多数揃っているので、やりたい事がある場合は適切なオプションを指定すると良いかもしれない。(例えば、dockerというオプションを指定することで特定のdockerイメージでJenkinsfileを実行することができる。詳細は記事末尾の参考資料にある公式ドキュメントを参照。)

### stageとsteps
stageの内部にはさらに`steps{}`というコンポーネントが存在する。一見`stage`と`steps`は重複する概念のように見えるが、実際は役割が異なる。
`stage`はCIにおける作業そのものを指し、必ず名前を必要とするコンポーネントである。一方、`steps`は具体的な処理を記述するためのコンポーネントで、名前を必要としない。
これらを踏まえてstages{}の内部を書くと以下のようになる。

```
stages{
    stage('Name'){
        steps { CIの作業内容 }
    }
}
```

### stepsの中身
stepsの中には具体的なCIの作業内容を記述する。
`sh ''`でシェルのコマンドを実行する処理を書けるので、大体これで事足りると思われる。
他にもJenkins Plugin等を用いることで便利な機能を簡単に導入することができる。プラグインを使う場合は、JenknisのWeb UIの方で事前にプラグインをインストールしておく必要となる。

(例)
- `archiveArtifacts 'file.tar.gz'`のように記述すれば、ビルド成果物をJenkins WebUI上からダウンロードできるようになる。
- JenkinsのJUnit プラグインを使えば、`junit 'testfile.xml'`でJUnitテスト結果の推移グラフをJenkins WebUI上に表示できる

## その他ちょっとテクい使い方
以上がJenkinsfileの書き方についての基本的な内容だが、Jenkinsfileの構文では様々な便利機能がサポートされている。その一例として、パラメータを定義して特定のstageをスキップできるようにする設定について紹介する。

### パラメータの設定
- `parameters{}`の`booleanParam()`を使い、パラメータを設定する。書き方は以下のような感じ
    - デフォルト値を`true`または`false`に設定することができる。`false`にしておくと、パラメータ付きビルド(後述)の際にチェックを入れない限り実行されない処理を作ることができる。
```
booleanParam(name: 'RUN_Build', defaultValue: false, description: 'Run build')
```

### stageの実行条件にパラメータを指定する
上で設定したパラメータが`true`の時のみ`stage`内の処理を実行するように記述する
具体的には、`when{}`内に`expression{}`を指定するとそれができるようになる。
書き方は以下のような感じ
```
when {
    expression { params.RUN_Build }
}
```

### パラメータ付きビルド
上述のようにしてJenkinsfileにパラメーターを定義すると、JenkinsのWeb UIに「パラメータ付きビルド」という項目が出現する。
![スクリーンショット 2023-11-30 15.32.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726845/4f13817e-8186-57cb-4c82-db8ee5270dfb.png)
「パラメータ付きビルド」をクリックすると、以下のようなチェックボックスが出現する。以下ではBuild, Test, Archive, Uploadの4つのパラメータを定義したが、チェックをつけた項目だけが実行される。
![スクリーンショット 2023-11-30 15.34.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726845/51fd88c6-5988-96c7-8fe0-407ea59f4d76.png)
このスクショの状態で「ビルド」を押すと`RUN_Upload`のみが実行される。

# 最後に
今回紹介した内容を全て記述すると、Jenkinsfileは以下のような形式になる。

```
pipeline {
    agent any
    parameters {
        booleanParam(name: 'RUN_Build', defaultValue: true, description: 'Run build')  
    }
    stages {
        stage('Build') {
            when {
                expression { params.RUN_Build }
            }
            steps {
                // CIの作業内容
                sh 'echo "Hello, Jenkinsfile!"'
            }
        }
    }
}
```

# 参考資料
- 公式ドキュメント
    - https://www.jenkins.io/doc/book/pipeline/
    - https://www.jenkins.io/doc/book/pipeline/syntax/