Jenkinsで処理を自動化するために必要な、パイプライン、ジョブ、シェルスクリプトの知識

:::note info
* はじめに
* パイプライン
    * パイプラインにおける、ジョブやシェルスクリプトの実行方法
        * ジョブを実行する版
        * シェルを実行する版
* ジョブ
    * ジョブ・パイプラインにパラメータを渡す
* シェルスクリプト
    * 変数の定義
    * 変数の使用
    * 引数のうけとり
    * シェルスクリプトで関数、引数、戻り値を使う方法
    * シェルスクリプトで算術演算
        * 参考サイト
    * 文字列として扱いたい場合
    * ディレクトリの存在チェック
    * 文字列の存在チェック
    * シェルでの変数展開、置換処理、正規表現
        * 参考サイト
* まとめ
:::

## はじめに
今回はJenkinsでビルド時に使用するパイプライン、ジョブ、シェルスクリプトについて説明していきます。

 

なかなか関連する処理を一通り説明しているサイトなどがなかったので、リファレンス的に様々な処理を把握できるように記載していきます。

 

以前のJenkins記事が設計、構築に関する情報をまとめていますのであわせて見ていただければと思います。

https://qiita.com/f4samurai/items/be9061a18f96c54065a1

## パイプライン
まずはパイプラインについて。こちらは以前もお話しましたが、コードを用いてビルド処理の流れを定義し、ビルドの状況を可視化することができます。
![20220922180430 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/dac84ac6-7c45-73e7-39fb-7dbd30f04124.png)

```
pipeline {
    agent any
    stages {
        stage('FetchSouceRepo') {
            steps {
                script {
                      //チェック処理
                }
                build job: 'ジョブの実行'
            }
        }
        stage('CreateWorkSpace') {
            steps {
                parallel(
                    //iOSジョブの実行
                    //Androidジョブの実行
                )
            }
        }
        
        stage('SetupCache') {
            steps {
                parallel(
                    //iOSジョブの実行
                    //Androidジョブの実行
                )
            }
        }
        
        stage('Import') {
            steps {
                parallel(
                    //iOSジョブの実行
                    //Androidジョブの実行
                )
            }
        }
        
        stage('Build') {
            steps {
                parallel(
                    //iOSジョブの実行
                    //Androidジョブの実行
                )
            }
        }
        
        stage('BackUp') {
            steps {
                //iOSジョブの実行
                //Androidジョブの実行
            }
        }
        
    }
}
```

上記パイプラインのコードはgroovyという言語を用いて記載を行い

GitHubで管理することも可能です。GitHubでパイプラインコードを管理しておくと

ビルド処理のバックアップや、修正時の反映が非常に楽になります。

 

GitHubでの管理は非常に簡単で上記のパイプラインのコードを

BuildPipelineJenkinsFileというファイルで保存してGitHubにリポジトリを作成

実際のパイプライン実行を行う時に以下のように設定することで実現出来ます。
![20230111191830 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/21989cd2-5c69-b6df-e22d-6ba975eba19b.png)

## パイプラインにおける、ジョブやシェルスクリプトの実行方法
地味にこのあたりの書き方についてあまり情報がなかったのでまとめておきます。

パラメータの渡し方などが参考になるかと思います。

## ジョブを実行する版
testというジョブを実行しています。

```
stage('CreateWorkSpace') {
steps {
parallel(

  iOS:{
    build job: 'test',parameters: [
     [$class: 'StringParameterValue', name: 'app_branch', value: "${app_branch}"],
     [$class: 'StringParameterValue', name: 'resource_branch', value: "${resource_branch}"],
     [$class: 'StringParameterValue', name: 'platform', value: "iOS"],
     [$class: 'StringParameterValue', name: 'unity_version', value: "${unity_version}"]
    ]
  },
  
 Android:{
    build job: 'test',parameters: [
     [$class: 'StringParameterValue', name: 'app_branch', value: "${app_branch}"],
     [$class: 'StringParameterValue', name: 'resource_branch', value: "${resource_branch}"],
     [$class: 'StringParameterValue', name: 'platform', value: "Android"], 
     [$class: 'StringParameterValue', name: 'unity_version', value: "${unity_version}"]
    ]
   }

)
}
}
``` 

## シェルを実行する版
test.shというシェルを実行しています。

```
stage('CreateWorkSpace') {
steps {
parallel(

　　iOS:{
　　　 sh "zsh ${WORKSPACE}/test.sh -P iOS -A ${app_branch} -R   ${resource_branch} -U ${unity_version}"
　　},

　　Android:{
　　　 sh "zsh ${WORKSPACE}/test.sh -P Android -A ${app_branch} -R ${resource_branch} -U ${unity_version}"
　　}

)
}
}
```

## ジョブ
パイプラインでもGitのリポジトリにアクセスしたり、シェルを実行し、ビルドやアップロード処理を行うことが出来ますが

「ビルド処理のみ行いたい」

「アップロード処理のみ行いたい」

などといった、個別処理を実現するために、ジョブを活用することがオススメです。

全体の処理はパイプラインで記載し、個別のステップはジョブを使うような方法です。

## ジョブ・パイプラインにパラメータを渡す
ビルドを行うときは、ビルドするブランチ、iOS、Androidなどのプラットフォーム、またUnityバージョンを指定してビルドを行いたくなる時があります。

その時使うのが、ビルドのパラメータ化という処理です。

パラメータの渡し方は以下のような様々な方法があります。
![20230111194047.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/8c78060e-132b-8f5e-2646-b52794dd536f.png)
今回は選択という、複数の選択から選ぶという方式について説明します。

選択の場合、後で参照するときの名前をつけ、

選択する値を１行ずつ定義します。
![20230111193516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/42d76cf1-9ade-2ee2-5967-37eea8a0e80c.png)

するとビルドする時に、ドロップダウンにて値を選択することが出来ます。
![20230111194340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/be8f45ae-2364-ef08-8ff9-f9919805e4e5.png)

ビルドの実行時、シェルで処理を行う場合は

以下のように${定義した名前}で選択した値を参照する事ができます。

```
zsh ${WORKSPACE}/test.sh -P ${platform} -A ${app_branch} -R ${resource_branch} -U ${unity_version}
```
 
## シェルスクリプト
ビルドの実行時には、パイプラインやジョブだけでは行うことが難しいファイル操作やビルド対象の収集などの処理が存在します。

その時に使うのがシェルスクリプトです。

シェルスクリプトの中でもよく使う処理を以下にまとめます。

 

## 変数の定義
変数の定義は以下のように、=で行います

他の言語のようにダブルクォーテーション""でくくったり、

=の前後にスペースはいらないのでご注意ください

```
UNITY_TARGET_BRANCH=develop

ASSET_TARGET_BRANCH=develop

UNITY_VERSION=2021
```

## 変数の使用
変数の使用は定義した変数の前に、$マークつけて使用します。

${変数名}という呼び方もでき、文字列を連携する時などに境界がわかりやすくなるため

${変数名}で統一することがおすすめです。

```
echo $UNITY_VERSION

echo ${UNITY_VERSION}



WORKSPACE_DIR=${BASE_DIR}/Workspace${UNITY_VERSION}/
```

 

## 引数のうけとり
パイプラインや、ジョブなどから引数を受け取る時には以下のようなコードを使います。

```
while getopts "P:A:R:U:" OPT; do
  case $OPT in
  P)
    PLATFORM=${OPTARG:-${PLATFORM}}
    ;;
  A)
    UNITY_TARGET_BRANCH=${OPTARG}
    ;;
  R)
    ASSET_TARGET_BRANCH=${OPTARG}
    ;;
  U)
    UNITY_VERSION=${OPTARG}
    ;;
  esac
done
A:
```

が、Aというオプションで、オプションが引数を持つときの処理で

引数は${OPTARG}で参照する事ができます。

```
${OPTARG:-${PLATFORM}}
```

は、シェルにおける変数の初期値定義を活用した処理になります。

上記の処理の場合、-Pオプションが定義されてない場合、${PLATFORM}で定義された値が使われます。

 

## シェルスクリプトで関数、引数、戻り値を使う方法
関数の定義、使用は以下のように行います


```
#定義側

function DisplayString() {

 RETURN_VALUE=$1

 echo $RETURN_VALUE

}



#使用側

FUNC_RETURN=$(DisplayString OutputString)



echo ${FUNC_RETURN}

#OutputStringと表示される
```

関数は、戻り値を使いたい場合は$()で囲んで呼び出し、引数は関数の後にスペースを開けて渡します。

引数を使用するときは、第1引数から$1、$2で参照します。

 

## シェルスクリプトで算術演算
シェルスクリプトで加減乗除の計算を強制的に行いたい場合は、
![20230113153228.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/af972ece-58ae-129f-48ab-1e43ee9f9761.png)

で全体を囲ってください。関数で引数で数値を渡して、中身で計算したい時に使います
![20230113153241 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/41ceff64-6126-4ff2-47c1-8604a6c26aac.png)


## 参考サイト
https://qiita.com/akinomyoga/items/9761031c551d43307374

 

 

## 文字列として扱いたい場合
上記の算術演算の似たパターンとして文字列として強制して扱いたい場合は

```
" "
```
で囲ってください。

```
' '
```
で囲った場合変数が展開されません。

以下のように関数呼び出しと誤解される場合に使えます


```
#定義側

function DisplayString() {

 #RETURN_VALUE=Hello $1　とすると関数呼び出しになりエラー

 #RETURN_VALUE='Hello $1'は変数が展開されずHello $1と表示される

 RETURN_VALUE="Hello $1"

 echo $RETURN_VALUE

}



#使用側

FUNC_RETURN=$(DisplayString World)



echo ${FUNC_RETURN}

#Hello Worldと表示される
```

 

## ディレクトリの存在チェック
ディレクトリが存在している時true

-d


```
#リソースワークスペースディレクトリがあれば削除

if [ -d ${WORKSPACE_DIR}/resource ]; then

 rm -rf ${WORKSPACE_DIR}/resource

fi
```

 

 

## 文字列の存在チェック
文字列が0の時true

-z オプションで

条件文を実行することでチェックできます

 

IDがとれるまでリトライするような処理を書く時などに使えます

```
 while [ -z "$INVALIDATION_ID" ]; do

 INVALIDATION_ID=$(ExecIvalidation)

 echo "retry INVALIDATION_ID:" $INVALIDATION_ID

 sleep 10

 done
```
 

## シェルでの変数展開、置換処理、正規表現
シェルでは変数を展開するための特殊な記法や、

置換するための書き方があります。また正規表現も使えます。

このあたりは頻繁に使うことは無いかもしれませんが、

コードを読むために必要となることがあるため一応心の隅に覚えておきましょう。

 

 



```
remote_all_branch=`git branch -r`



remote_branch_array=(${(f)remote_all_branch//origin\//})
```
変数展開と、置換処理を使用

改行区切りで保存されたremote_all_branchをorigin/を取り除いた上で配列に保存する

 

 

```
if [[ $find_dir =~ ^.*${branch// /}/ ]];then
```
正規表現マッチと置換処理を使用

$branchから空白を除去して、末尾に/を追加する

  develop

↓

develop/

こちらの値を使い$find_dirにある文字列と前方一致した時trueを返す

 

 

 

## 参考サイト
[bashの変数内文字列置換まとめ - Qiita](https://qiita.com/aosho235/items/c36568830a8d47288284)
[Zsh 変数メモ · GitHub](https://gist.github.com/sho-t/d9cdf8271b3de7c4238739e523490542)
[Bashで正規表現マッチした文字列を取り出す - Qiita](https://qiita.com/rockhopper/items/bee538ab4c6aabcd6b0f)

 

## まとめ
今回はJenkinsでビルドを行うために必要な

パイプライン、ジョブ、シェルスクリプトについて、全体を把握できるように

よく使う処理についてリファレンス的にまとめてみました。

 

誰かのお役に立ちましたら幸いです。

 

[エンジニア採用特設サイトはこちら](https://www.notion.so/f4samurai-Engineer-Recruiting-33fd41dc956242f6a172ad52038fc653)