Github + jenkins pushを検知してジョブ実行

## はじめに
船井総研デジタルのoswです。業務でjenkinsに触れることになったので学習記録を残します。参考になる方がいらっしゃれば幸いです。

## 学習環境
- jenkins 2.375.3（AWS EC2)
- Github

## 以前の学習内容
手動でジョブ実行、Githubからクローン/テスト実行までを学習しました。

https://qiita.com/fsd-osw/items/46b14be933ac4be5d0be

## Githubへpushと同時にジョブを実行する方法
調べてみるとほとんどの場合、jenkinsにプラグインを入れて実現しているようです。ところが同じプラグインを入れてるはずが、同じ項目が表示されなかったり、表示されているものの、同じことをしても403エラーが返ってきたりとかなりハマりました。
（プラグインが更新されて、などの影響もあるかもしれません）

色々試した中で実際にpushしてジョブ実行まで確認できた方法２つを記します。
1. webhookを使う方法
1. Gitフックを使う方法

## webhookを使う方法
こちらの方がシンプルでgithub側も推奨しているようです。ここでは次を前提とします。
- pushしたことを検知してジョブを走らせる
- pushされたリポジトリをクローンする

### ジョブ設定
- パイプライン
    - ジョブ設定 - [ビルド・トリガ] - [GitHub hook trigger for GITScm polling]にチェック
![ジョブ設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/6deb329f-8263-397c-cf0d-7c102c336815.png)
    - pipeline script
 ```
pipeline {
    agent any
    stages {
        stage('clone') {
            steps {
                // webhookの送信元リポジトリがここで指定したリポジトリ、ブランチと一致していたらジョブが実行される
                // 指定するブランチを変えれば、ブランチ別にpushを検知できる
                git branch: "main",
                url: "https://github.com/ofsda/test"
            }
        }
    }
}
 ```

### webhookの登録
push対象のリポジトリにwebhookを登録する
- Payload URL: JENKINS_URL/github-webhook/
    - JENKINS_URL: [jenkinsダッシュボード] - [Jenkinsの管理] - [システムの設定]で確認
- Which events would you like to trigger this webhook?
    - プッシュした際にwebhookを飛ばしたいので、[Just the push event]を選択

![webhook設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/805eb53d-7037-9f96-dd07-c65c156cbab6.png)

webhook登録後、画像のように緑のチェックが付けば疎通確認できているので問題ありません。赤くなっている場合は登録したwebhookを選択し、[Recent Deliveries]でログをご覧になってみてください。

![webhook登録後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/3e6ac0bd-b195-1f35-a677-41a0e90334da.png)

### pushしてジョブを実行する
ここまででpushを検知してジョブを走らせる仕掛けは完了です。ただ、作ったジョブは事前に手動で１回実行する必要があります。実行しないとwebhookが飛んでもジョブが起動しません。

下記画像は1度手動でジョブを実行した後に差分をpushした直後の画像、また、その実行結果です。

![pushを検知.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/fdf7ecde-0bad-91db-8717-913e91e00a53.png)
![実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/abb7d25f-7a94-dedc-558e-abe9c6a22299.png)

## Gitフックを使う方法
### Gitフックとは
Gitフックを今回初めて触ったのでドキュメントを置いておきます。gitの各種コマンド（commit / pushなど）が実行される前、後など決められたタイミングで定義した処理を走らせることができるようです。

コマンド、タイミングの組み合わせは.git/hooks/に存在するファイル名で定められており、そのファイルに処理を定義します。

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF

### ジョブ設定
github側がgitフック実行時に外部アクセスを制限してるようで、クライアント側で実行するpre-pushで実現しました。ここでは単純にフリースタイルのジョブを作成し、それが起動できれば良しとします。処理の中身は問いません。

### ビルド・トリガURLを取得する
Gitフックに設定するビルド・トリガURLを取得するには、ジョブ詳細画面の「ビルド実行」を右クリック、「リンクのアドレスをコピー(E)」を選択し、メモしておきます。

コピーされるURLは「ビルド実行」にマウスホバーした際、左下に現れるアドレスです。(Chromeの場合）

![ビルド・トリガURL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/98730cef-9ac1-7703-45cb-43cd650a9fc7.png)

### APIトークンを作成する
[jenkinsダッシュボード] - [jenkinsの管理] - [ユーザーの管理] - [既存ユーザーを選択] - [設定] - [APIトークン] - [トークン新規追加]で生成したトークンをメモしておきます。

### Gitフック pre-pushを設定
まず、.git/hooks/pre-push.sampleをpre-pushに名前を変更します。
その上で下記コマンドを記載します。先程取得したビルド・トリガURL、トークンを使います。

```bash:pre-push
#!/bin/sh

curl -X POST --user <トークンを生成したユーザ名>:<トークン> <ビルド・トリガURL>
# 例) curl -X POST --user develop:11b01ee068975c75b180a57d http://xxxxxxxxxxxxxxxxxxxxxxxxx:8080/job/githook-test-job/build?delay=0sec
```

このGitフックを使う場合は、作成したジョブを最初に手動で実行させる必要はないようです。pushすればそのままジョブが起動します。

![gitフックでジョブ起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/522980c9-883e-b3c3-513b-380c0435f23e.png)

## おわりに
ジョブ実行するのにGitフックを使うことはなさそうですが、方法の1つとして覚えておこうと思います。

普段見ない.gitの中を触れたのはいい経験でした。