【初心者】いまさらJenkinsに入門する (2) GitHubとの連携

# 1. はじめに
- 前回の記事「[【初心者】いまさらJenkinsに入門する (1)インストールと基本操作](https://qiita.com/mksamba/items/39bce04872440279a142)」で、Jenkinsのインストールや基本操作を確認した。今回はGitHubとの連携について確認する。

# 2. やったこと
- GitHubとJenkinsを連携させる設定をする。
- GitHubのリポジトリが更新されたら、Jenkinsのジョブを起動し、GitHub上の更新されたindex.htmlを取得、Webサーバ(nginx)へコピーして、Webサーバのコンテンツ更新を行う。

# 3. 構成図

## 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/3e63d60f-119f-0869-e81d-2c2e646fd0d7.png)

## 詳細
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c9cdf739-6215-3dc3-605c-801ece3bea4f.png)


# 4. 手順

## 4.1 【GitHub】プライベートリポジトリの作成
- プライベートリポジトリ「jenkins-connect」を作成する。（このリポジトリの内容が更新されたら、Jenkinsに通知が行われ、Jenkinsがファイルを取りに来るように設定していく。）

## 4.2 【GitHub】Personal Access Token の作成
- JenkinsからGitHubにアクセスできるよう、GitHubのPersonal Access Tokenを作成する（後でこのPersonal Access TokenをJenkins側に設定する）。
- Settings -> Developer Settings -> Personal access tokens -> Tokens (classic) -> Generate new token (classic) でトークンを作成しメモする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/7ac426cb-b555-e7d8-9fb1-35c12508af43.png)

## 4.3 【Jenkins】GitHub認証情報の登録
- Jenkins側で、4.2項で作成したGitHubのPersonal Access Tokenを使えるように登録する。
- Jenkinsの管理 -> 認証情報 -> System -> グローバルドメイン -> +Add Credentials で認証情報登録画面へ。
- 以下のように登録する。
    - 種類：ユーザー名とパスワード
    - スコープ：グローバル
    - ユーザー名：GitHubのユーザー名
    - パスワード：GitHubで発行したPersonal Access Tokenの文字列
    - ID：このCredentialの名前（なんでもよい）

![jenkins01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/727f59f2-5bb1-601d-0b83-d14234c0a6d9.png)

## 4.4 【nginx】Jenkinsサーバからの接続許可

- ユーザ ec2-userで、Jenkinsからscpで接続してindex.htmlを上書きできるようにしておく。(index.htmlがあるディレクトリのオーナーをec2-userに変更しておく)
```
$ sudo chown ec2-user /usr/share/nginx/html
```

## 4.5 【Jenkins】nginx サーバへのscp接続用の秘密鍵保存

- Jenkinsのジョブから、nginxのEC2インスタンスにscp接続するため、nginxインスタンスのユーザ ec2-user の秘密鍵をJenkinsインスタンス内の適当なディレクトリ(今回は/home/ec2-user/)に保存し、パーミッションを設定する。

```
$ chmod 600 privatekey.pem
```

## 4.6 【Jenkins】ユーザ jenkinsのsudoers設定
- ジョブ内のシェルスクリプトはユーザjenkinsで動作されるため、ユーザjenkinsがscp実行時にec2-userにsudoできるようにしておく。

```
$ sudo visudo
# 最後尾に以下の行を追加
jenkins ALL=(ALL) NOPASSWD: ALL
```

## 4.7 【Jenkins】ジョブ作成
- GitHubのリポジトリに更新があった際に自動的に起動され、GitHubのリポジトリ内のファイル(index.html)を取得し、nginxサーバへscpするジョブを作成する。
- 前提条件として、Jenkinsのプラグイン「GitHub」が導入済であること。
- 新規ジョブ作成 -> フリースタイル・プロジェクトのビルド でジョブ「github-connect」を作成し、以下の項目を設定する。

### ソースコード管理
- GitHubプライベートリポジトリにアクセスできるように設定する。
    - ソースコード管理: Git
    - リポジトリURL： 4.1項で作成した、GitHubプライベートリポジトリのURL
    - 認証情報：　4.3項で作成した、Credentialを選択
    - ビルドするブランチ：　今回はブランチの指定はしないので空欄にする
    
![jenkins02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/7607c4dc-0bd7-d02f-e566-ee73f3d75390.png)

### ビルド・トリガ
- GitHubプライベートリポジトリの資材更新があった場合にビルドが行われるように設定する。
    - 「リモートからビルド」にチェック。GitHub側からのWebhookを使用するため。認証トークン名は適当に設定する(今回はgctoken)。
    - 「GitHub hook trigger for GITScm polling」にチェック。

![jenkins03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/51cc642c-2b88-2788-42a7-dc6da29c3580.png)

### Build Steps
- GitHubから取得したindex.htmlをnginxインスタンスにscpするスクリプトを記述する。
- 「シェルの実行」を選択し、以下のコマンドを記述。ec2-userにスイッチユーザした上で、Jenkinsのこのジョブのワークスペース内に保存されたindex.htmlを、scpでnginxインスタンスの既定のディレクトリにコピーする。

```
sudo -u ec2-user scp -i /home/ec2-user/privatekey.pem /var/lib/jenkins/workspace/github-connect/index.html  ec2-user@10.0.100.92:/usr/share/nginx/html/index.html
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/bb7f5cf0-c794-59d6-75b2-0d28ae6f5e5d.png)

## 4.8 【Jenkins】GitHub Webhook用SRCIPのアクセス許可
- Jenkinsのインスタンスはパブリックサブネットに存在し、EIPが付与されている。
- GitHubからのWebhookを受け取るため、GitHubのSRCIPからのhttpアクセスを許可する。
- GitHubのSRCIPのCIDRは「[GitHubのサイト](https://api.github.com/meta)」のhooksの項目でリストとして確認可能。

## 4.9 【Jenkins】APIトークンの作成
- GitHubからのジョブ起動を可能にするため、GitHub側に渡すためのAPIトークンを作成する。
- 右上のユーザ名(今回はmksamba) -> 設定 -> APIトークン -> トークン新規追加　でAPIトークンを作成し、トークン文字列(一度しか表示されない)をメモする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/57745188-9145-8c10-1666-9d3add3d9a02.png)

## 4.10 【GitHub】Webhookの設定

- git push が行われた際に、JenkinsのJobを起動するためのWebhookを作成する。Webhookの設定にて 4.9項で作成したAPIトークンを使用する。
- Webhooksの設定
    - Payload URL：　
        - フォーマット：　http://[Jenkinsサーバのユーザ名]:[JenkinsサーバのユーザのAPIトークン]@[JenkinsサーバのFQDN/IP]:[Jenkinsサーバのポート]/job/[ジョブ名]/build
        - 設定例：　http://mksamba:1111a0aab4e2633a22229606196c901111@10.10.10.10:8080/job/github-connect/build
    - Content Type: application/x-www-form-urlencoded
    - SSL verification: Disable (今回はSSLを構成せず、httpでJenkinサーバへアクセスする必要があるため)
    - Which events would you like to trigger this webhook?: Just the push event. 

![jenkins04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/a14471a8-2a41-8082-3428-2496e2bc2b64.png)

## 4.11 動作確認

- ジョブを実行する前のnginxサーバのindex.htmlは以下（ChatGPTに作ってもらった適当なhtml）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c71d9efe-c774-1c24-54a8-8fd982a14fa5.png)

- GitHubのプライベートリポジトリに新しいindex.html(背景色だけ変更したもの)をgit pushする。

```
$ git add index.html
$ git commit -m "version 2"
$ git push
```

- git push 後、GitHub側でWebhookが発動していることを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/bc433c86-939e-a3e7-9c6f-c7f5d0ce4471.png)

- Webhookをトリガに、Jenkins側でジョブが起動、成功していることを確認する（ビルド#17が成功）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/2adc6fe4-6430-b157-e0a2-eff5e3470b90.png)

- ジョブの実行結果として、nginxサーバのコンテンツが更新されていることを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/5df12984-8122-e6ea-3ac5-53e903058ab6.png)


# 5. 参考サイト

- [JenkinsにGitHub認証情報を登録してJenkinsfileからジョブを作成できるようにする](https://qiita.com/karaage578tech/items/e6d6f53baf977cf4556b)
- [JenkinsでCI環境構築チュートリアル ～GitHubとの連携～](https://ics.media/entry/2869/)

# 6. 所感
- 少し入門できてきた気がするので、次回は複雑なジョブなどにチャレンジしてみたい。