Jenkinsの運用に必要な関連知識

:::note
* はじめに
* Jenkinsで行っていること
* Jenkinsで自動化を行う時に必要な知識
    * Jenkinsで作成するシステムの評価ポイント
    * Jenkinsに関する知識
    * Jenkinsのスクリプトに関する知識 
    * シェルスクリプト
    * OSのコマンド
    * UnityのAssetBundleビルドに関する知識
    * Gitなどソースコード管理システムに関する知識
    * リソースのアップロードに関する知識
* まとめ
:::

## はじめに
ソフトウェア開発では、テスト、ビルド、デプロイなどの作業をCIツールを使って自動化することはよくあります。
エンジニアだけでなく、プランナー、デザイナーといった職種の方も使うため、安定運用することが非常に重要なシステムです。

弊社ではCIツールとしてJenkinsを採用することが多く、

今回、社内でJenkinsの運用改善を行ったため、その情報を共有いたします。


## Jenkinsで行っていること
プロジェクト内でJenkinsは以下のようなところで使われています。

Unityアプリケーションのビルド
Unityアセットバンドルのビルド
アセットバンドル、画像、サウンド、動画などリソースファイルのサーバーへのアップロード
今回は特に、構成要素が多く処理が複雑化していた

アセットバンドルのビルド
アセットバンドル、リソースファイルのアップロード処理
について詳細に掘り下げて説明していきます。


## Jenkinsで自動化を行う時に必要な知識
まず、Jenkinsを構築する時に必要な知識を、他のプロジェクトへの共有を考慮して整理してみました。
![20220922195219.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/9081afcc-6efd-2a3f-0994-4a766d2b9c3e.png)
プロジェクトごとに細かな実装や構築内容は変わってきますが、要素を分解しておくと、そのまま流用できるものと、手順が参考になるものが明確になるため、情報交換が円滑になり、属人性も下げることもできます。

 

次に、個々の要素について詳細に説明していきます。

 

## Jenkinsで作成するシステムの評価ポイント
まず、Jenkinsで作成するシステムはどのような点で評価されるのかを整理しておきましょう。

ここができていないと、システムを変更、更新した時に以前より使い勝手が悪くなりチームのアウトプットを低下させることにもなります。

 

例として、３点わかりやすい評価点を説明します。

* Jenkinsで単位時間あたりにこなせる仕事の量（ビルド時間、並列性）
* 安定性（稼働率、ビルド失敗する確率）
* 復旧手順の容易さ
 


１つ目はビルドの時間や、同時に実行できるビルドの数です。特にゲームでは大量の素材を使用するため１回のビルドが長くなりがちです。

ビルドが完了しないと、動作の確認が行えないため、ビルドにかかる時間をいかに短くするか、また並列実行なジョブにするかということが重要なポイントです。

 

2つ目はビルドの安定性です。ビルドは繰り返し使用し、一つ一つの時間がかかるものであるため、ビルドが確実に成功するようにしておくことは非常に重要です。

一度稼働させるとビルド時間が長くなり、検証にも時間がかかるため、Jenkins構築し運用を始める前の段階で取りうるパラメータを変えてのテストをしっかりしておきましょう。

 

3つ目は復旧手順が容易であるかということです。

長く運用していると、ハードディスクの故障などで急遽Jenkinsサーバーを再構築することも発生します。

そうなった時のため、Jenkinsのスクリプトや、設定値、システム構成をドキュメント化し残しているか？という事が、システムの評価要素となります。

 

## Jenkinsに関する知識
そして、Jenkinsをインストールするために必要なセットアップのための知識が必要です。

特に、Jenkinsはビルドを行うために様々なアプリ(ツール)と連携するため、基本的な処理を行うためにどのようなプラグインが必要かという知識も必要となってきます。

 

セットアップする時に注意したいのは外部サービスに接続するときの、キーを設定するなどの権限付与の方法です。

JenkinsではCredentialsという仕組みを用いて外部サービスのキーを保存することができます。

プラグインがインストールされていれば、Jenkinsの管理-Securityの項目にManage Credentialsに存在しています。
![20220922185259.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/de68c617-69f2-57e8-d92c-866aa2f84426.png)

![20220922185314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/09f3627b-c456-f340-16e5-dced41587f1d.png)

参照するときはJenkinsのスクリプトで、CredentialsProviderを使用し取得します。

エラーが出やすい部分なのでセットアップ時にエラーがでたら、権限周りの処理を確認するのが良いかと思います。

 

加えて仕事で使う場合、複数のビルドを複数のPCを用いてさばけるようにするために、マスター、スレーブ（エージェント）の構成でJenkinsを立てることができることも把握しておくと選択肢が広がります。

 

## Jenkinsのスクリプトに関する知識 
現在のJenkinsでは、シェルの実行などの単体の処理を行うジョブに加えて
初期化・ビルド、デプロイなどの複数のジョブをスクリプトを書くことで、連続して実行・また制御することができます。この仕組がパイプラインです。

 

可視化されたパイプラインの構造は以下になります。
![20220922180430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190574/fb67f14f-c65b-e07e-ad87-e8ed57f5a7fd.png)
詳細など一部削除しましたが、こちらのパイプラインを作るスクリプトは以下になります。
```
pipeline {
    agent any

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

パイプラインは、Scripted Pipelineという記法と、Declarative Pipelineという記法がありScripted PipelineはGroovyをベースとしたスクリプト言語的性質を持ち、if文などで複雑な制御を行うことができます。

Declarative Pipelineはシンプルな記載方法となっており、scriptというタグを使うことでScripted Pipelineで使用できるif文なども使用可能です。

 

基本的にはDeclarative Pipelineを使うことが推奨されているので、Declarative Pipelineをベースとして使い、分岐や条件が複雑になる時はscriptタグを利用し制御文を記載するようにしましょう。


## シェルスクリプト
Jenkinsのジョブでビルドを行う時に便利なものがシェルスクリプトです。

シェルスクリプトでは、OSのコマンドや他の言語を呼び出すことで、

素材などのファイルのコピーや削除処理、その他素材の加工処理を順序だって実行することができます。

 

言語仕様的には高度な抽象化などを行う仕組みはないため、誰でもすぐに使いやすいですが、変数の展開、関数、引数の取り扱いなどシェルスクリプトの特有の記載方法があり他人のコードを理解する上でも重要ですので、一通り把握しておきましょう。


## OSのコマンド
ビルドを行う時には、シェルスクリプトの中で、ファイル、ディレクトリの作成、コピー、削除を行うOSのコマンドを利用し、ビルドの準備を行うことがあります。

 

繰り返しビルドを行う場合には前回の生成物をいかに利用するかが重要になってきます。

その時使用するのが、cpやrsyncなどのコマンドです。

ファイルが消えたときの処理、サイズが変わらないがタイムスタンプが変わる時の処理などが問題になりやすいため、コマンドの活用方法を正しく理解しておきましょう。

 

## UnityのAssetBundleビルドに関する知識
UnityのAssetBundleビルドの仕組みは日々変化、発展しており

所属しているプロジェクトによって、AssetBundleManager、AssetGraphTool、Addressable Asset Systemなど使われているAsssetBundleビルドの仕組みを理解しておく必要があります。

加えて、基盤となるAssetBundle自体の仕組みを理解しておけば、アップデートなどで変化があった場合も正しい判断ができます。

このため、基盤の仕組み、ビルドの仕組み両方を把握しておきましょう。


## Gitなどソースコード管理システムに関する知識
アセットバンドルや素材などのリソースビルドを行う際には、ゲームに使われる大量のリソースをいかに早く、Gitなどのソースコード管理システムから取得することが重要になってきます。

 

ゲームのビルドにおいては、日々少しずつリソースが追加されるため、差分だけをいかに効率的に取得するかといいう点が重要でGitなどのソースコード管理システムのコマンド、仕組みも理解をしておく必要があります。

 

## リソースのアップロードに関する知識
ビルドの最終工程としては、作成したものを、開発環境や本番環境に反映する作業が必要になります。

ビルドが正常に終わっても正しく反映出来ていないと、更新した作業を確認することが出来ません。

* 素材の差分のみを反映する仕組み
* 常に新しいもの上書きする仕組み
* 素材の反映状況を確認する仕組み

など、頻繁に使う作業などを把握した上で、Jenkinsでのビルドの仕組みに加えて、確認用のツールも容易しておくと良いかと思います。


## まとめ
少々長くなりましたが、今回はJenkinsで処理を自動化する際に必要な要素の全体像を整理してみました。

この情報があれば、現在課題となっているところを見つけ、深堀りするための目次に使えるのではないかと思います。

 

実際に使用するコマンド、機能、注意しておくべき所は別途まとめる予定ですのでご期待ください！

 

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