jenkinsでgithubからクローンする

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

## 学習環境
- Windows 11 (WSL2 Ubuntu)
- jenkins 2.387.1 (AWS EC2)

## githubからクローンする方法
jenkinsでgithubからクローンするには大きく分けて次の方法があるようです。jenkinsに限らず、個人で扱う場合は1の方法でも良いかもしれませんが、セキュリティ的な観点では`Deploy key`を登録して個別にアクセス許可を与える方が良さそうです。

1. 全てのリポジトリ(public / private)にアクセス可能な設定をする
    1. `jenkins`ユーザの`公開鍵`をgithubに登録する
    1. `Personal Access Token`を登録する
1. 特定のリポジトリ(public / private)にアクセス可能な設定をする
    1.アクセスしたいリポジトリに`Deploy key`を登録する

## 全てのリポジトリ(public / private)にアクセス可能な設定をする
### `jenkins`ユーザの`公開鍵`をgithubに登録する
こちらは普段からgithubで公開鍵認証をしてる方なら直感的にわかる方法かと思います。jenkinsのジョブが走る際、ジョブの実行ユーザは`jenkins`のようです。

そのため、`jenkins`ユーザの公開鍵を作成し、それをgithubに登録します。ただ、`jenkins`ユーザはログインシェルが設定されていないため一時的に設定し、用が済んだら元に戻しておきます。

別ユーザで鍵を作成、chownなどしてから`jenkins`ユーザの.sshに入れても良いと思います。

```bash
# jenkinsユーザのログインシェルを確認する（/bin/false なのでjenkinsユーザに切り替えられない）
$ sudo cat /etc/passwd | grep jenkins
jenkins:x:995:993:Jenkins Automation Server:/var/lib/jenkins:/bin/false

# シェルを変更するため chsh をインストールする。EC2環境ではこれを利用しますが、その他は chsh を指定していただければ良いかと思います
$ sudo yum -y install util-linux-user

# jenkinsユーザのログインシェルを設定する
$ sudo chsh -s /bin/bash jenkins

# jenkinsユーザのログインシェルを確認する（/bin/bash なのでjenkinsユーザとしてログイン可能）
$ sudo cat /etc/passwd | grep jenkins
jenkins:x:995:993:Jenkins Automation Server:/var/lib/jenkins:/bin/bash

# jenkinsユーザに切り替え
sudo su - jenkins

# 公開鍵を作成する。今回はパスフレーズなしにします
$ ssh-keygen -t ed25519 -N '' -C ''

# 作成した公開鍵の中身をまるまるメモしておく
$ cat .ssh/id_ed25519.pub

# githubの公開鍵を取得する
$ ssh-keyscan -t ed25519 github.com > ~/.ssh/known_hosts

# jenkinsユーザからログアウト
exit

# ログインシェルを元に戻す。これでjenkinsユーザにはログインできなくなる
$ chsh -s /bin/false jenkins
```
githubの公開鍵を取得する件については[補足](#補足)を参照してください。

あとはコピーしておいた公開鍵をgithubに登録します。
1. githubにログインし、右上のプロフィールアイコンから`Setting`を押下
![githubアカウント設定メニュー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/e63daabb-799a-de82-00fe-b61220056a96.png)
1. 左ペインの`SSH and GPG keys`を押下
![SSHキー登録メニュー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/7c619c66-1a3f-f0eb-85b2-da8717e6201d.png)
1. `New SSH key`を押下
![公開鍵の登録画面に遷移.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/b0b9414b-babf-b701-863c-3dbb49090c00.png)
1. Titleを入力, Keyにはメモした鍵をそのままを入力し、`Add SSH key`を押下
![公開鍵を登録.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/6513ddd0-1baa-199a-9d0f-9ebe113f862f.png)

このようにすると、ジョブの作成時に認証情報を指定せずにプライベートリポジトリもクローンできるようになります。（クローンするためのURLはSSHを指定）

下記は「フリースタイル」でジョブを作成、「ソースコード管理」をONにしてプライベートリポジトリを指定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/bf8a85b9-4a7f-6c9c-8013-9258b76fcf20.png)

githubに登録した`jenkins`ユーザの公開鍵を削除すると下記のようにエラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/a9967a4c-15ae-f059-4526-4f7fd3856d0b.png)

#### 補足
githubに公開鍵を登録する場合、予めgithubの公開鍵を`known_hosts`として登録しておく必要があります。これはsshなどで接続する際、ホスト認証をする過程で`known_hosts`を見に行く訳ですが、初回接続時にプロンプトが表示され`yes`と入力しないと`known_hosts`に登録されません。

jenkinsのジョブを実行した場合、プロンプトは表示されないためそのままエラーとなりジョブ自体が失敗します。そのため、予め`known_hosts`として登録しています。

### `Personal Access Token`を登録する
`jenkins`ユーザの公開鍵をgithubに登録する公開鍵認証の方法では鍵の生成、githubに生成した鍵の登録、githubの公開鍵を`known_hosts`に登録、と結構手間がかかります。`Personal Access Token`を登録する場合は公開鍵認証よりもだいぶ楽になります。

1. githubにログインし、右上のプロフィールアイコンから`Setting`を押下
![githubアカウント設定メニュー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/e63daabb-799a-de82-00fe-b61220056a96.png)
1. 左ペインの`Developer settings`を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/b3fd3c51-fd3e-53b2-16c6-346169b13978.png)
1. 左ペインの`Personal access tokens` >  `Tokens(classis)`を押下し、`Generate new token` > `Generate new token(classic)`を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/45f31a46-15d2-b0fd-a21e-e48adea9e39e.png)
1. `Note`にトークンの表示名を付けます。`repo`にチェック（リポジトリの操作が可能）し、ページ下部の`Generate token`を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/f108e8c8-38a7-c10c-d6d3-7950b5790000.png)
1. 生成されたトークンをメモしておきます。2度と見れないようですので、メモしてないとトークンを作り直すことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/20022675-a95f-95a6-e83a-af1821db9ec6.png)
1. `jenkinsダッシュボード` > `Jenkinsの管理` > `Manage Credentials` > `System` > `グローバルドメイン` > `Add Credencials`を押下。下記情報を入力して`Create`します。
    1. ユーザー名: githubアカウント名 (Treat username as secretにチェックを入れるとユーザー名が隠蔽され、認証情報一覧にはIDが表示されます)
    1. パスワード: 先程メモしたトークン
    1. ID: 認証情報の識別子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/fd4f7cf6-7a9c-acb6-77e5-5d3bee8d84da.png)

公開鍵を使った時と同様、「フリースタイル」のジョブを作成し、認証が通ることを確認します。クローンで指定するURLは`HTTPS`を指定し、`認証情報`には先程作成した認証情報を選択します。正しく設定出来ているとエラーは出ません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/3bef6d86-8176-eeeb-a672-4bba3bbdaf32.png)

ここで、認証情報を外すとエラーが発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/f94c6c55-4804-88c8-f596-2a4156fd834c.png)

## 特定のリポジトリ(public / private)にアクセス可能な設定をする
### アクセスしたいリポジトリに`Deploy key`を登録する
これも公開鍵を登録することで認証を通します。流れは[jenkinsユーザの公開鍵をgithubに登録する](#jenkinsユーザの公開鍵をgithubに登録する)とほぼ同じです。

異なるのは作成した公開鍵を`Deploy key`として登録するか否かです。`Deploy key`として登録するには次のようにします。

1. アクセスを許可したいリポジトリの`Settings` > `Deploy keys`を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/39900994-f65c-c849-21f1-4693669dee38.png)

1. `Add deploy key`を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/1f792632-dad8-2483-b419-fb81a0fdbf59.png)

1. `Title`を入力, `Key`には作成した公開鍵の中身を入力し、`Add key`を押下。（Allow write accessをチェックするとpushが出来るようになるようです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/c2803065-4bee-e64a-1e76-7e7968ff35c0.png)

github側に登録した公開鍵を削除し、`Deploy key`を登録したリポジトリとそうでないリポジトリを並べて設定してみると、次のように`Deploy key`を登録したリポジトリは認証情報も設定せずエラーにはなりません。（クローンはSSH方式）

|リポジトリ名|`Deploy key`登録|
|:-:|:-:|
|test|なし|
|test2|あり|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/990dc236-cb62-4c9e-98fb-f077e7fede14.png)

testリポジトリは`Deploy key`を登録してませんが、`Personal Access Token`を使えばエラーは発生しません。（クローン方式を`SSH` -> `HTTPS`に変更する必要あり）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/a41af215-983c-1196-6734-65ad8a5d0657.png)


## おわりに
公開鍵の作成はちょっと手間ですが、認証情報を設定する必要もなくなるので便利ですね。