Jenkinsを手探りで社内ローカルに立てて詰んだ話

 　
SC AdventCalendar 2017　15日目の投稿です。
一人よがりな読みづらい文章になっていたらすみません...。
※分かり辛い所がありましたらコメント等でご指摘頂けると幸いです


## **まえがき**
今回は、かねてからやりたかったJenkinsでのCI実施(CI環境構築)をやってみました。
最初はかっこつける為にAzureでやろうとしましたが、諸事情で社内のローカルマシン内で実践しました。
今年の夏頃、プロジェクト作業中に「待ち」が発生した時にちまちまやっていたので、
かなり断片的＆中途半端な情報となります点をご容赦ください。

ということで、本稿の主旨は「Jenkinsの構築の際に"何をやったか","どこでハマったか"」等々の覚え書きになります。

※**覚え書き故に、丁寧語ではなくなっているところがあります**
※**2017/12/15時点の「Jenkins 2.89.1」の設定画面とは多少異なっている所があります**


## **やる前の知識**

CIについて2016年上半期頃にプロジェクト関連で少し調べた。
Jenkinsというオープンなソフト？枠組み？みたいなのがあって、
それを使って自動ビルド⇒テスト⇒デプロイ
みたいなことをやる、ということは知ってた。
CLI？パイプライン？なにそれ？状態。

## **やりたかったこと**

社内GitBucketと連携させて、特定のリポジトリ(今回は「Selenium_RandD」)を監視。
gitに上げられたソース(C#)を自動ビルドして、エラったらプッシュした人にメールで怒る。

## **結果として**
過程が長いので先に結果を書きます。
とりあえずメールは飛ばないものの、gitのpushを検知して、
ビルドエラーならビルドエラーとして検出することはできました。

あと、試みが一段落してから感じたのは
「こういう試みは本とか買って体系的にやるのがいいんだろうなー」ということですね。
(各設定項目に対する知識がないので、何故エラーになっているかを突き止めるのも大変だったり。。)

ただ、作業とは直接関係ない色々な周辺知識が必要になる分、得るモノも大きいので、
泥沼に嵌りながらも成長したいぜ俺は！って人には是非お勧めです。
(最小の努力で最大の成果を求めるBeLazyな人にはオススメしません)

## **さっそくやってみる**
### その前にJenkinsって何よ
  CI(継続的インテグレーション)と呼ばれる、
「ビルド/ソース管理～デプロイ周りを自動でイケイケにしようぜ」
っていう手法の実現に組み込まれる、OSSのインテグレーションツールです。

詳しい事は適当にググってこの辺の記事を読んで頂ければ。

　Qiita記事)　
　  [Jenkinsとはなんぞや？](https://qiita.com/ko8@github/items/e6e058976d48d3fc3424)

※作業の際の参考リンクについては、数が多いので記事の最下部に羅列します

---
### **1. Jenkinsのインストール**
とりあえず[公式](https://jenkins-ci.org/)からJenkinsをインストールしてみる。
「インストール位ちゃらっといけるだろ」と、適当にインストーラーに従って進める。

結果としてローカルマシン内にJenkinsのサーバーが勝手に出来上がった。
.Netterとしての礼儀を尽くし、IISを開いてチェックしたところ
残念ながらIISには追加されていなかった。

※ここらへんから「あー、Javaの知らない世界だわ」と引け目を感じ始める
　(Jenkinsの内部はJavaで動いています)
  
---
### **2. 新規JOBの作成～設定**
とりあえずローカルには展開できたので、Azureに展開しようかと考えたけどお金とかの理由で断念。
(社内IPとAzureで疎通させなきゃいけないし)

  デプロイ先はともかく、Jenkins自体のやれることは変わらないはずなので、
早速ジョブを作り、設定してみることにした。
↓はダッシュボードと呼ばれるGUIベースのメイン画面
![terminal.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/46901fd3-671e-8106-b688-2decb5b2e818.jpeg)


  以後は各ステップごとに記述。

---
#### **新規ジョブ作成**  
![select_job_name.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/ffc68672-3771-4642-50b4-03c420d403d4.jpeg)
まずはジョブの名前を決めて、「フリースタイルプロジェクトのビルド」として作成。
  

次にプロジェクト名としてやらせたいことの詳細をつらつら書く。
![General.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/9c0fc161-1828-da77-861a-067d36ce6328.jpeg)  

　　いくつかの参考サイトで挙げられていた＆今回はGitHubの互換ともいえるGitBucketを使うので
　　一度「GitHub Organizationかなー」と選択して作ってみたところ、
　　設定項目に"Project～"とか"Organization～"など見慣れない単語がわらわら出てきて
　　怖くなったのでやめた。

---
#### **GitBucket(プラグインにまつわる設定)**  
![GitBucket.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/a59ee63c-079c-ee11-7422-fe9a95b83600.jpeg)

  大項目「GitBucket」の設定。
  ここらへんは参考サイトの通りに項目を埋めては動かし、埋めては動かし、の繰り返しだった。 

GitBucketでソースを管理してまっせ、ということをJenkinsに教えて監視させる為の設定となる。 

  ということで「URL」欄に、Gitbucket上でリポジトリのCloneを作る時のURLを入力する。
やりたいことの要件外だが、なんとなく良さそうなので「古いビルドの破棄」にもチェックをつける。
  とりあえずビルドの保存日数＝30、保存最大数＝5で登録。


  
**ハマりポイント)**
①「URL」欄の末尾は".git"をつけない

---
#### **ソースコード管理**
![SourceCodeManagement.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/5f435258-2067-7a80-0bfc-9193fbac9fa7.jpeg)
大項目「ソースコード管理」の設定。
ここらへんも参考サイトの通りに試行錯誤。

ソースコードを管理している＆Jenkinsで監視する、GitBucket内にまつわる細かい設定をしていく。

まずは「Git」にチェック。
「リポジトリURL」の入力欄はさっきの「URL」欄とは違い、".git" まで入力する。
「認証情報」欄にGitbucketにログインするユーザーIDとパスを設定。

「ビルドするブランチ」はテストなので適当にmasterで。

「リポジトリブラウザ」プルダウンは"Gitbucket"を選択して色々いじってみたが
中々うまくいかないので、"(自動)"を選択した。
※結局、"(自動)"でうまくいった  
また、GitBucket側の当該リポジトリの、[Settings]⇒[ServiceHooks]にも、
  Webhookアドレス(http://【JenkinsサイトURL(ポート番号込み)】/gitbucket-webhook/)を登録しなければならない。
  ※今回は (http://【Jenkins展開先の社内ローカルマシンIP】:8080/gitbucket-webhook/) で登録

   **ハマりポイント)**
    ①「リポジトリURL」欄の末尾は".git" を**つける**
    ②「リポジトリブラウザ」プルダウンは"(自動)"で
    ※リポジトリブラウザが正直何かよく分かっていないけど、
  　たぶんJenkinsがリポジトリを見に行くときに経由するブラウザなのかなーと推測(そのまんま)



---
#### **ビルドトリガ**  
![BuildTrigger.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/07559fac-dac1-a4aa-5d5f-d65ce9b9b88f.jpeg)
  大項目「ビルドトリガ」の設定。  
今回はGitBucketのプッシュを検知＝「C#ソースをビルドする」動きのトリガーになりますよ、という設定をする。
ここは参考サイトを見てすんなりいった。  
  やりたいことは
「Build when a change is pushed to GitBucket」にチェックを付けるだけで事足りていたが、
  なんとアドレスを叩くだけでビルド指示が飛ばせる(いつでもどこでもビルドさせられる！)
ということで、せっかくだから「リモートからビルド」も設定。  
認証トークンは適当に[test]にした。

  
---  
#### **ビルド環境**  
![BuildEnvironment.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/558aa4bc-5235-04b5-7a51-878e204b3fb6.jpeg)
  大項目「ビルド環境」の設定。  
「コンソール出力にタイムスタンプを追加する」にチェックを入れてさっさと次へ。

  
---  
#### **ビルド**
![Build.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/445fedbb-4ae2-3dab-2bbd-b4c13dc0f056.jpeg)
  大項目「ビルド」の設定。
ここは参考サイト上のJenkinsのバージョンが古く、***メチャクチャ詰まった***

要するにJenkins単体ではC#というか.Netをビルドすることはできないので、
ここで.Netのコンパイラを指定してね！ということらしい。

ということで  「ビルド手順の追加」より、MSBuildを選択。
(VisualStudioのビルドボタン押下時に、裏でコンパイルしてくれているのがMSBuild君です)
「MSBuildバージョン」欄は"デフォルト"**ではなく**明示的に使用するバージョンを入力する。
「MSBuildビルドファイル」欄は、今回C#コードを書いた「SeleniumTest\SeleniumTest.sln」に設定。
  (当該Jobのホームディレクトリからのパスで記述する ~~ココも超詰まった~~ )

  
  **ハマりポイント)**
    ①MSBuildは、
[ダッシュボード画面] ⇒ [Jenkinsの管理] ⇒ [Global Tool Configuration]より、
明示的に名前をつけてMSBuildの実体を指定する。
    ⇒.NetFrameworkの保存場所やVisualStudioの保存場所から実体のMSBuild.exeを指定する
      (今回はC:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe を指定した)
      ![MSBuild.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/b5121ff7-109a-6052-4961-510a71314b51.jpeg)    
    ②ビルドファイルはJenkinsのホームディレクトリ下にある、当該Jobのホームディレクトリからのパスを指定する。
  
---
#### **ビルド後の処理**
![AfterBuild.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/660c3563-6e89-7a2f-3985-8efe7c1d788d.jpeg)
  大項目「ビルド後の処理」の設定。
  ここは今回やりたい事と、ばっちりマッチするケースの参考サイトが無く、
  いろんな参考サイトのTIPSを取り入れ、死ぬほどトライ＆エラーした。
単純に「C#をビルドして、コンパイルエラーが出たらメールを送る」だけなのに...。
  
  まず、そのままではビルドエラーが起きても、Jenkinsさんはエラーとして扱ってくれなかった。
なのでJenkinsのパッケージとして「LogParser」という、ログ内の文言に応じて
Jenkinsのジョブ結果を変えてくれるパッケージをインストールする。

   [Console output(build log)parsing]を選択して、
   [Mark build Unstable on Warning]と、
   [Mark build Failed on Error]にチェックを入れる。  

当然のようにLogParserも「入れただけで動く」なんて易いものではないので
「ログ内のどの文言を見て何をするか」設定をしてあげないといけない。

   [Use global rule]にチェックを入れて、
  Jenkinsの本体が入っているホームディレクトリ[C:\Program Files (x86)\Jenkins]直下に、
    BuildErrorRules.txt(名前は任意)というファイルを追加。
    ※このファイルのルールに則り、ビルド時のログ内文言に正規表現をかけ、
MSBuildのエラーや不安定といった状態が認識され、Jenkinsのジョブ結果に反映される仕組み

  で、あとはE-mail通知として宛先等々を良しなに設定。
 これも、[ダッシュボード画面] ⇒ [Jenkinsの管理] ⇒ [システムの設定]より、
E-mailの設定(SMTPサーバーの設定、ポートとか)をする。

今回は社内環境なので社内メールサーバーの情報を入力した。(たぶん公にしたら怒られる)
  ![E-mailServer.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/54d6984e-ceef-8c82-8c1e-c78b7e8d48d8.jpeg)



  
  
　**ハマりポイント)**
    　①MSBuildを指定しただけでは、ビルド時にエラーがあってもJenkinsはエラーとみなしてくれない
    　⇒Jenkins側のエラー判定はBuild時に実行するexe等の返り値が0であるか否か、を見ているようで
    　　MSBuild内でエラーが発生しても、ゲイツがしっかりエラーハンドリングをしてくれている為に
　　MSBuild.exeの最終的な返り値が0になってしまう。⇒Jenkinsは正常終了とみなしてしまう

   　②LogParserのBuildErrorRules.txtの設定(ルールファイルの指定)は、絶対パスで指定する。
    ![LogParser.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/a4fe1cf3-40c2-d8a6-306e-87a522414447.jpeg)  
  
  
　③E-mail通知に関しても、サーバーの設定だけでなく[Jenkinsの管理]⇒[システム設定]の際に、
   　　当該Jenkinsサーバーの管理者のメールアドレスを設定しないと機能しない。
    ![AdminMailAddress.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/d6834366-fc15-a3ba-eb8c-ff229c6b6a65.jpeg)




ルールファイル[BuildErrorRules.txt]の中身）

```
error /.エラー./  
error /.error./ 
```

---
### **3. 検知させてみる**
  当該GitBucketのリポジトリ内の、指定した.slnソリューション内のC#コードで
  適当にビルドエラーを起こさせるようにして、コミット＆プッシュ。
  (今回はコンパイルエラーの赤線が出るようにした状態でコミット＆プッシュ)
  ![makeError.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/9c9c23ec-b188-a311-93cf-7b1e576c1671.jpeg)
フラストレーションからか暴言が飛び出してしまう。

---
### **4. 検知結果をみる**
  作成したJob ⇒ コンソール出力より結果を見ます。
  色々苦労しましたが、見事ジョブ結果が赤くなりました！
  「Finished:FAILURE」になってるところが喜びポイントです。
  (LogParserがうまく設定できるまでは、ビルドがエラってもジョブが成功扱いになってた)

  ![builderror.jpg](https://qiita-image-store.s3.amazonaws.com/0/131674/9cb3d419-f973-678e-96f3-acc1021f6065.jpeg)

---
### **5. 力尽きる**
   残されたメール届かない問題ですが、社内メールサーバの情報を入力してたりで
   個人の力を越えた何かの存在を感じたので、この辺で断念しました。
  (個人でやる場合はGmailの公開されているサーバーを使ったりするらしいです)

## **あとがき**
今回は社内環境＆自己学習時間を使って～等の制約があったので、
次は 個人PC + GitHub の組み合わせでリベンジしようと思っています。
(できれば年末年始とかの暇な時に...)

## **作業にあたって参考にしたリンク集**
　もはやどの作業にどのリンクを見たか曖昧なので、羅列する形式で...  
・[Jenkinsを使った自動テスト環境を作る（前編）]
(https://knowledge.sakura.ad.jp/5293/)
・[JenkinsとSeleniumを使ってWebコンテンツの自動UIテスト環境を作ろう！]
(https://ics.media/entry/6031)
・[.NET開発者のためのJenkins入門]
(http://www.atmarkit.co.jp/fdotnet/chushin/greatblogentry_09/greatblogentry_09_01.html)
・[イマドキの GitBucket + Jenkinsの連携は Jenkinsfile と GitHub Organization Folder プラグインでこんなに簡単（になる予定）]
(https://qiita.com/kounoike/items/52fa35ca5813d0edc7b7)
・[GitBucketとJenkinsの連携の設定方法。(うまくいかないときに確認するところ)]
(https://qiita.com/YoshinoriN/items/54dd19f4862fb50dbbec)
・[JenkinsとGitBucketを連携し、pushされたら自動的にソースを取得する(GitBucket Plugin)]
(http://symfoware.blog68.fc2.com/blog-entry-1632.html)
・[.NETとGitとjenkinsでCI環境を構築する方法(2) - jenkinsの初期設定]
(http://barikata.hateblo.jp/entry/2013/10/29/203942)
・[GitBucket の Webhook（Service Hooks、Payload URL）を Jenkins のビルド・トリガにする方法]
(http://obel.hatenablog.jp/entry/20161030/1477838785)
・[Jenkins の MSBuild プラグインのパス設定場所]
(https://qiita.com/nkkn1008@github/items/a1a6e325ef09f5eda575)
・[Azure 上に Jenkins を使って CI 環境を構築する]
(http://gooner.hateblo.jp/entry/2016/12/25/132543)
・[Jenkinsでスクリプト実行, jenkins-cli, 結果をメール通知, 拡張メール設定]
(https://qiita.com/tukiyo3/items/83bfbb22f84ab0bf8d14)
・[Jenkinsのワークスペースパスがおかしい]
(http://woodcode.blogspot.jp/2014/02/jenkins.html)
・[Jenkins Visual Studio で自動ビルド その２]
(http://blog.somof.net/?p=1090)
・[JenkinsのLog Parser Pluginでコンパイルエラーを抜けなくチェック]
(https://qiita.com/jin_yokoyama/items/0f2c4569c37ecd8b70d6)
・[Jenkins がもっと便利になるおすすめプラグイン 8 つ]
(https://blog.fenrir-inc.com/jp/2012/12/jenkins_plugins.html)
・[Jenkins構築手順]
(https://techinfoofmicrosofttech.osscons.jp/index.php?Jenkins%E6%A7%8B%E7%AF%89%E6%89%8B%E9%A0%86#na92cb2a)
・[StyleCop の結果を Jenkins Violations Plugin で表示すると違反箇所のソースコードが表示されないことがある 解決策その２]
(http://odashinsuke.hatenablog.com/entry/20121230/1356876614)