Jenkins

#0. やりたいこと

1.C++のソースをリポジトリから取得し、コンパイルする。
2.単体テスト(cppunit)を実行する。
3.インテグレーションテストを実行する。
4.テストカバレッジを取得する。
5.インスペクションツールを使用してソースコードの規模を取得する。
6.結果をレポートで表示する。

以下も可能ならやりたい
7.分散ビルド(Windows/Linux)
8.使用したいプラグインが無ければ自作
9.C++のソースからドキュメントを作成(Doxygen)

#1. 環境構築
## 1-1.必要なもの
- 継続的インテグレーションサーバ(CIサーバ)
- ソースコード管理システム
- ビルドサーバ

今回はCIサーバとビルドサーバを同一筐体として検証してみる。

## 1-2.Windows環境にインストール

jenkins-2.121.1.zipをダウンロードし、インストール。
特に難しいことは無いので省略。

# 2.C++のソースをリポジトリから取得し、コンパイルする。
以下の手順でジョブを作成する。
1.新規ジョブを作成する。
2.ソースコード管理システムを設定する。
3.ビルド・トリガを設定する。
4.ビルドタスクを設定する。
5.ビルド後の処理を設定する。

## 2-1.新規ジョブを作成する。
[ホーム]-[新規ジョブ作成]-[フリースタイル・プロジェクトのビルド]
「Enter an item name」に名称を付け、「OK」ボタンをクリック。
ここで作成した名前がjenkinsの「jobs」フォルダの下にフォルダが作成され、ビルドの成果物等が保存される。

## 2-2.ソースコード管理システムを設定する。
とりあえずGitを指定し、リポジトリURLのみを指定。

## 2-3.ビルド・トリガを設定する。
とりあえず定期的に実行で1時間間隔にする。
### 定期的に実行
分、時、日、月、曜日をスペースで区切って記入する。

|項目|値の範囲|
|:--|:--|
|分|0～59|
|時|0～23|
|日|1～31|
|月|1～12|
|曜日|0(日曜日)～6|

使用できる記号は以下

|記号|使い方|
|:--|:--|
|*|すべての値を表す記号。分なら毎分|
|,|「1,2,3」のように集合を表す。分なら「1分、2分、3分」|
|-|「1-3」のように範囲を指定する。分なら「1分、2分、3分」|
|/|「*/10」のように一定間隔を指定する。分なら10分間隔|
|H|ハッシュを表し任意の時間に実行する|

上記を参考に「H */1 * * *」と指定する

## 2-4.ビルドタスクを設定する。
Windowsバッチコマンドの実行からビルドする。

2つのcppファイルをコマンドラインでコンパイルしてみた。

```bat:コマンドライン
cl file1 file2
```

でVS2017用コマンドプロンプトでは実行できたが、Jenkinsからはコマンド入力したら赤の波線が表示され、エラーになる。
実行してもエラーになった。VS2017用コマンドプロンプトを呼び出す必要がある。

### Makefileの作り方
https://hondou.homedns.org/pukiwiki/index.php?Jenkins%20for%20C%2B%2B%20Project

http://gurigumi.s349.xrea.com/programming/visualcpp/makefile1.html

うまくいかなかった。

## MSBuildの使い方
[MSBuildでコマンドラインからビルドする](http://sh-yoshida.hatenablog.com/entry/2017/05/27/012755)

"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild" <ソリューションファイル.sln>

MSBuildにパスが通っていないため、フルパス指定にしている。
環境変数を設定すればパスを指定しなくても成功した。

## 環境設定の変更
[ホーム]-[Jenkinsの管理]-[システムの設定]
環境変数に以下のように設定
キー：PATH
値：${PATH};"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\";"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE"

(追記)MSBuildプラグインがあった。

# 3.単体テスト(cppunit)を実行する。

## 3-1.Visual Studio上でC++の単体テストを実行する
Google C++ Testing Framework
Visual Studio 2017 バージョン 15.5 以降には標準で組み込まれているはずだが表示されない。
**あきらめた。**

** 3-2.単体テストの勉強
https://docs.microsoft.com/ja-jp/visualstudio/test/unit-test-basics

テスト対象のプロジェクトとテスト用のプロジェクトを分離。
テスト対象のプロジェクトはアプリケーション(EXE)からスタティックライブラリ(lib)に形式を変え、プロジェクトを参照するように変更。

## MSTestでエラー
```bat
MSTest /testcontainer:<Testプロジェクト名.dll>
```
で以下のエラーが発生する。

テスト コンテナー 'dllファイル' またはその依存関係の 1 つを読み込むことができませんでした。テスト プロジェクト アセンブリを 64 ビット アセンブリとしてビルドすると読み込むことができません。テスト プロジェクト アセンブリをビルドすると きに、プラットフォームとして "Any CPU" を選択します。64 ビットのプロセッサー上で 64 ビット モードでテストを実行するには 、[ホスト] タブでテスト設定を変更し、32 ビット プロセスでテストを実行する必要があります。エラーの詳細: ファイルまたはア センブリ '<dllファイルパス>'、またはその依存関係の 1 つが読み込めませんでした。モジュールはアセンブリ マニフェストを含んでいなければなりません。

## MSTestのエラーの回避策
vstest.consoleを使用する。
https://msdn.microsoft.com/ja-jp/library/jj155796.aspx
インストール先
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow

```bat
vstest.console <Testプロジェクト名.dll> /Logger:trx
```
trx(Test Results File)形式でログを出力する。

MSTestプラグインを入れていれば「ビルド後の処理」で「Publish MSTest test result report」が選択できるので、テスト結果を解析できるようになる。

### 注意点
「ビルド終了後にワークスペースを削除する」設定にしないと、テストケースが倍々で増えていくことになった。

## MSBuildでエラー
Visual Studioではコンパイルできるのに、MSBuildではエラーが出る場合はコンパイルオプションの設定が違うのが原因。
MSBuildにオプションに以下のようにVisual Studioと同じ設定を指定すれば成功した。

 /p:Configurationx=Debug /p:Platform=x86

# 4.テストカバレッジを取得する。
OpenCppCoverage
https://github.com/OpenCppCoverage/OpenCppCoverage/releases
#プラグイン
## 古いビルド履歴の削除
プラグイン名：Discard Old Build
使い方：ジョブのGeneralタブの先頭部分に「古いビルドの破棄」が表示される。

## 5.インスペクションツールを使用してソースコードの規模を取得する。
「StepCounter Plugin」を使用する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187121/2ef19fcf-8e7f-10d0-c01e-9fa290448073.png)

## MSBuildプラグイン
プラグインをインストール
[ホーム]-[Jenkinsの管理]-[Global Tool Configuration]
でMSBuildのインストール先を指定する。
![undefined]()

# 8.トラブル対応

### 8-1.Mavenでコンパイルができない
ソース取得はされるが、コンパイルができない原因は、Proxyの設定がされていない可能性が考えられる。
手動でMavenをインストールして、conf/settings.xmlファイルをのProxyの設定を修正する。
Jenkinsの設定で、自分でインストールしたMavenを追加すればよい。

# 9.プラグイン
## 9-1.Discard Old Builds
### 9-1-1.バージョン
1.05(2020/12/6時点)

### 9-1-2.設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187121/c479bc4c-1522-e2c4-c5ff-46e71c1dcc0f.png)

|説明|和訳|
|:---|:---|
|Days to keep builds|ビルドを維持する日|
|Max # of builds to keep|保持するビルドの最大数|
|Interval to keep old builds (by days)|古いビルドを保持する間隔（日数）|
|Interval to keep old builds (by # of builds)	|古いビルドを保持する間隔（ビルドの数による）|
|Status to discard|破棄するステータス|
|Min Logfile size in bytes|最小ログファイルサイズ（バイト単位）|
|Max Logfile size in bytes|最大ログファイルサイズ（バイト単位）|
|Regular expression|正規表現|