Jenkins で GitHub のイベントを受けてゴニョゴニョする準備

## はじめに
「AWS で CI 環境を構築」のための準備です。
今回は GitHub のイベント通知を Jenkins で受けて、ソース展開するところまで。

リポジトリ毎に設定するのは面倒なので、全リポジトリが対象となるようにします。

## インストール

### OS 環境

JDK

```
# yum -y install java-1.8.0-openjdk-devel
# alternatives --config java
```

jq 

```
# yum install jq
```

### AWS セキュリティグループ

GitHub からの通知を受けるため、AWS 側にセキュリティグループ(SG)を設定している場合は、インバウンドルールを追加します。

GitHub のグローバルIPアドレスは、以下のようです。
https://help.github.com/articles/what-ip-addresses-does-github-use-that-i-should-whitelist/

```
192.30.252.0/22
```
![スクリーンショット_2017-01-08_10_07_06.png](https://qiita-image-store.s3.amazonaws.com/0/69410/6c46c175-91d7-6cd7-747d-ff818e97a324.png)


### Jenkins

https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Red+Hat+distributions

かなり端折りますが、大筋で以下です。

```
# wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

# yum install -y jenkins

# chkconfig jenkins on
# service jenkins start
```
ブラウザで 8080 ポートにアクセスして、動作していれば、インストール完了です。

## 設定

### Jenkins

Jenkins 側のジョブ設定を見ていきます。

「新規ジョブ作成」で「フリースタイル・プロジェクトのビルド」を選択して下さい。
プロジェクト名は、お好みで。

![スクリーンショット 2017-01-07 23.24.48.png](https://qiita-image-store.s3.amazonaws.com/0/69410/7c7b6d04-c4e7-c716-c7ea-9787659470f9.png)


(当初 SonarQube での利用を考えていたので sonarqube になっています。)
![スクリーンショット 2017-01-07 23.01.37.png](https://qiita-image-store.s3.amazonaws.com/0/69410/5b57c05f-3c66-6ff6-d36f-0d13b828584d.png)


GitHub からの通知をパラメータとして受けるため、「ビルドのパラメータ化」で以下の設定にします。
**型「文字列」 名前「payload」 デフォルト「none」**
![スクリーンショット 2017-01-07 22.57.47.png](https://qiita-image-store.s3.amazonaws.com/0/69410/6ef9a330-c62d-11da-c99c-c686c66baae9.png)

「ソースコード管理」ですが、自分で ソース管理するので「なし」で。
![スクリーンショット 2017-01-07 23.05.02.png](https://qiita-image-store.s3.amazonaws.com/0/69410/f7b04e94-6cab-78b6-9208-9c3cd431b0f8.png)

「ビルド・トリガ」は「リモートからビルド」です。
認証トークンは、適当な長さで、適当に決めてください。何でもいいです。
後で GitHub 側に設定します。
![スクリーンショット_2017-01-07_23_06_45.png](https://qiita-image-store.s3.amazonaws.com/0/69410/c8bae1a4-6891-85d9-b4a9-fc37d22d7b0c.png)
URLはここにヒッソリと書かれていますので、トークンと共に、メモしておいて下さい。

```
リモートからビルドを実行するには次のURLを使用します: JENKINS_URL/job/sonarqube/build?token=TOKEN_NAME もしくは、 /buildWithParameters?token=TOKEN_NAME
```

今回のオススメポイントは、ここ！
**「ビルドの前にワークスペースを削除する」のチェックはしない**でください！
削除してしまうと、毎回、git clone が必要となり、処理に時間がかかってしまいますので！
![スクリーンショット_2017-01-07_23_12_42.png](https://qiita-image-store.s3.amazonaws.com/0/69410/e667ed2b-f0dd-cba3-e253-e76c34ba3167.png)

「ビルド」は「シェルの実行」を選択します。
GitHub からの通知を受けて、そのパラメータが payload という環境変数に代入されています。
jq コマンドを使って、パラメータを取得します。

|変数名|内容|
|----|----|
|OWNER|リポジトリのオーナー名(未使用)|
|BRANCH|ブランチ名<br>(タグ名(refs/tags/)の場合は sed 不要)|
|NAME|リポジトリ名|
|URL|git clone (ssh) 用 URL<br>(jenkins ユーザで git clone できるように ssh 鍵を GitHub に設定しておくこと)|
|ID|ハッシュ値(未使用)<br>(削除イベントの際は 000...000 となるので注意)|


![スクリーンショット 2017-01-08 1.33.42.png](https://qiita-image-store.s3.amazonaws.com/0/69410/325bd689-819c-62c7-fce7-f37ca8f8c07a.png)


シェルの処理内容は、以下です。

  1. 既に clone されてる (ディレクトリが存在する) か？  
   まだなら、clone
  1. clone したディレクトリに移動
  1. フェッチ
  1. reset hard
  1. ゴニョゴニョ

「ビルドの前にワークスペースを削除しない」ので、前回のビルドの clone が残っており、fetch は高速に完了します。


```bash
#!/bin/bash

export PATH=/usr/bin:/usr/local/bin:$PATH

param() {
  echo $payload | jq -r $1
}

OWNER=`param '.repository.owner.name'`
BRANCH=`param '.ref' | sed "s:^refs/heads:remotes/origin:"`
NAME=`param '.repository.name'`
URL=`param '.repository.ssh_url'`
ID=`param '.after'`

echo $URL
echo $BRANCH

if [ ! -d $NAME ]; then
  git clone $URL
fi

cd $NAME

git fetch origin
git reset --hard ${BRANCH}

# ゴニョゴニョ
```

ビルド後の処理は、特にありません。
![スクリーンショット 2017-01-07 23.22.48.png](https://qiita-image-store.s3.amazonaws.com/0/69410/b6f2abc6-ab75-90c4-3bde-646226f2cac8.png)

## GitHub
GitHub 側の設定を見ていきます。

ポイントは、**Webhooks の設定をリポジトリ毎にしない (アカウントで 1回だけ設定する) こと**です。
そうしておけば、リポジトリが増えても、特にメンテナンスが必要ないからです。

アカウントの Settings にある Webhooks を追加します。

URL は、先にメモした URL に token を足して、以下になります。

```
<Jenkins ホスト>/job/<プロジェクト(ジョブ)名>/buildWithParameters?token=XXXXXXXXXXX
```

Content-type ですが、ハマリポイントです。**json ではない**です。
**application/x-www-form-urlencoded** にします！！

![スクリーンショット_2017-01-07_23_54_50.png](https://qiita-image-store.s3.amazonaws.com/0/69410/fba5d92d-c437-1918-b95d-f038bf85faa0.png)

これで準備OKです。
適当なリポジトリに対して、適当なブランチに Push してみてください。
「Recent Deliveries」部分が、Jenkins との通信が、成功なら「緑のチェック」、失敗なら「赤のビックリ」です。

![スクリーンショット 2017-01-08 0.09.31.png](https://qiita-image-store.s3.amazonaws.com/0/69410/bc381c3c-12cf-d347-2ee5-e494bccd14c4.png)

![スクリーンショット 2017-01-08 0.17.10.png](https://qiita-image-store.s3.amazonaws.com/0/69410/47aab174-de88-3637-7bc5-70b3a5625087.png)

「Recent Deliveries」は「Redeliver」ボタン押下で **任意の履歴を再送可能**です。

![スクリーンショット_2017-01-08_0_20_24.png](https://qiita-image-store.s3.amazonaws.com/0/69410/5979dcb4-9638-fe63-b018-d5c4e741f10d.png)

## 動作確認
 1. Jenkins サーバに OS アカウント(ec2-user)で ログイン
 2. sudo su jenkins; で jenkins ユーザにスイッチ
 3. cd; で ホームに移動
 4. cd workspace; で ワークスペースに移動
 4. リポジトリが clone されているなら、成功している

## おわりに
GitHub の Push イベントをフックして、git clone された状態にまでなりました。
後は、SonarQube と GitBook、自動テスト 等を足していきます。