Kotlin で GitHub のプライベートリポジトリをクローン

# はじめに
Kotlin で [JGit](https://github.com/eclipse-jgit/jgit) を用いて Git Clone を使ってみたので書き残しておきます。
具体的な状況としては、プログラムの設定に利用するファイルを GitHub に置いてどこからでも引っ張ってこれるようにしたものの、肝心の引っ張ってくる方法をどうしようか悩んでいた。といった感じです。

初めのほうは JGit や GitHub のトークンについて書いているので、コードだけを知りたい人は読み飛ばしてもらって構いません。

# JGit 

https://github.com/eclipse-jgit/jgit

Apache に在籍する人が作成しているらしい。
提供されている機能はリポジトリの Readme の features セクションに書いてあり、リポジトリの作成、クローン、コミット、プッシュ、マージ、リベースなど多岐にわたるようです。

# 導入
Maven で落としてくる。
以下のリンクは 2025 年 3 月 12 日時点での最新版

https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit/7.1.0.202411261347-r

# やったこと
全体としてはトークンの発行と Git Clone の利用だけです。


プライベートリポジトリからのクローンになるので、認証がない状態ではコードにたどり着くことができません。そのため、まずは GitHub のリポジトリを閲覧する権限を持つトークンを発行しました。

## GitHub のトークン
GitHub の認証を自動的に通すためのトークンですが、現在

- Personal Access Token (PAT)
- Fine-grained personal access token

の 2 種類が存在します。
PAT の方は [GitHub による解説ページ](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) で classic と書かれている通り、 FPAT に比べて安全性が低いため一般的な用途での利用は推奨されていません。
対して Fine-grained Personal Access Token は操作が可能なリポジトリの指定や、その他アクションの制御といった多くの面でよりきめ細やかな設定が可能です。

今回は一般的な用途(リポジトリのクローン)なので利用が推奨されている FPAT を利用します。

## トークンの発行
個人設定のページを開き、左側のタブの一番下にある "Develiper settings" に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/79ba4244-cde9-454d-9eaa-879e3959409a.png)

Developer settings のページでも左タブの一番下にある "Personal access token" のプルダウンを開き、Fine-grained tokens を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/5cf9920c-6e03-4f2d-a2cc-24709eeae6c5.png)

ページ右側にある "Generate new token" を開き、認証をしてトークン作成画面に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/56572aab-0ae5-417f-bffa-3863f7e6536b.png)

特にトークンの有効期限 (Expiration) と、アクセス権限 (Permissions) は重要な部分なので設定ミスがないようにしてください。
特定のリポジトリ(非公開含む / 複数選択可)のみへのアクセスを制御したい場合には "Repository access" を "Only select repositories" にしたあと、 "Select repositories" でリポジトリを選択します。

次にトークンへ付与する権限を設定します。今回はリポジトリのコンテンツをクローンしてくるだけなので "Permissions" の "Contents" を Read-Only に設定します。
設定すると Contents 以外に Metadata という項目も自動的に Read-Only が付与された状態になりますが、これはリポジトリの検索や情報の取得に必要なものなのでそのままにしておきます。

最後に、入力した情報に間違いが無いか、表示されるトークンの有効期限に間違いがないかを確認して "Generate token" を押してトークンを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/72b39ade-0f15-4718-98c1-b6638ea92929.png)

作成したトークンが表示されるので安全な場所にメモっておきましょう。
万が一流出した場合や忘れてしまった場合にはトークンの再生成もできますが、それまでに発行したトークンが無効になるので取り扱いには注意しましょう。

ここで作成したトークンを次のセクションで利用します。

# JGit on Kotlin で Git Clone
本題の Kotlin で Git Clone を行うコードを書いていきます。
必要となるものは
- リポジトリのコンテンツを展開するためのディレクトリ
- リポジトリの URL
- リポジトリにアクセスするためのトークン

の 3 つです。


まず、リポジトリを展開するためのディレクトリですが、これは Java の [File](https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/io/File.html) 型の値になります。
```Kotlin
val f: File = Paths.get("").toFile()
```
などで取得しておきましょう。

後の 2 つはそれぞれ取得しておいてください。

クローンするコードは以下のようになります。
```Kotlin
fun gitClone(
    destination: File,
    repositoryUri: String,
    token: String
): Boolean {
    return runCatching {
      Git.cloneRepository()
        .setDirectory(destination)
        .setURI(repositoryUri)
        .setCredentialsProvider(
            UsernamePasswordCredentialsProvider(token, "")
        )
        .call()
        .close()
    }.onFailure { e -> 
      e.printStackTrace() 
    }.isSuccess
}
```

UsernamePasswordCredentialsProvider なんていう結構危なそうな名前しておいて、トークンでの認証にも対応しているところがすごいですね。

# 終わりに
JGit さん、機能もさることながらクセもすごいと言われている様子。

# リンク
https://github.com/eclipse-jgit/jgit

https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit/7.1.0.202411261347-r

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens

https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/io/File.html