2020年のMavenリポジトリの作り方


# はじめに

Javaのエンジニアであれば何だかんだでMavenリポジトリを使うことは非常に多いと思います。Gradleであっても使いますしね。

OSSなどはセントラルリポジトリから落とすとして自作のライブラリの管理をどうしていますか？ ローカルだけで開発していれば`mvn install`で事足りますが、CI/CDを行っていたりチームや組織でライブラリを共有している場合はそうもいきません。

という分けで今回はMavenで作成したライブラリを公開するための方法に関してまとめました。ちなみに2020年8月時点でのおすすめはGCSをリポジトリにする方法です。

- Maven Central Repositoryに登録
- OSSのリポジトリサーバを立てる
- GitHub Pagesを使う
- GitHub Packages + Actions を使う
- S3/GCS/Azure Blobにリポジトリを構築する
- GCP Artifact Registry

# Maven Central Repositoryに登録

もっとも正攻法の手順となります。登録手続きはややめんどくさいですが、利用時にリポジトリの追加作業が無いのは大きなメリットですね。OSSのライブラリとして利用者を広げたい時には使うと良いと思います。

- [OSSRH Guide](https://central.sonatype.org/pages/ossrh-guide.html)
- [Maven Central Repository に公開手順](https://qiita.com/RYOOMA/items/a7bda0251790609d2cb4)

# OSSのリポジトリサーバを立てる

次に考えられるのがOSSのリポジトリサーバを立てる事です。社内リポジトリとしてはこれが一般的かもしれません。
[Nexus Repository Manager](https://help.sonatype.com/docs)や[JFrog artifactory](https://jfrog.co.jp/artifactory/)が有名です。突貫で作る場合ならばJenkinsなどのCIサーバの.m2リポジトリをApache等で公開してしまうという方法もあります。細やかな管理は出来ませんが動くは動くので最低限の機能で手早く作りたい時は選択肢ですね。

# GitHub Pagesを使う

GitHubに静的コンテンツをホスティングできる「[Github Pages](https://pages.github.com/)」を活用する方法があります。一昔前に流行りましたね。
基本的な考え方としては`mvn deploy`でいったんローカルにライブラリをデプロイして、`mvn site`でGithub上にPushします。セキュリティ/可用性をGitHubに任せる事が出来るのでかなり便利です。

詳しい手順は以下サイトで詳しく解説されています。

- [[小ネタ] GitHub Pagesを使ってMavenの簡易的なリポジトリを作ってみた](https://dev.classmethod.jp/articles/maven-repository-githubpage/)

個人で作ってるライブラリをPublicに公開するのに便利な方法です。無料ですし。

# GitHub Packages + Actions を使う

GitHub PagesをMavenリポジトリとして利用するのはややハック的な所がありますが、最近GitHub Packagesとして正式な方法としてmaven libaryを公開できるようになりました。

- [GitHub Packagesで利用するために Apache Maven を設定する](https://docs.github.com/ja/packages/using-github-packages-with-your-projects-ecosystem/configuring-apache-maven-for-use-with-github-packages)

まずはpom.xmlに以下のようにデプロイ先を登録します。

```pom.xml
    <distributionManagement>
        <repository>
            <id>github</id>
            <name>GitHub OWNER Apache Maven Packages</name>
            <url>https://maven.pkg.github.com/{YOUR_NAME}/{YOUR_PRJ_NAME}</url>
        </repository>
    </distributionManagement>
```

手動でやることもできますが秘密鍵を管理するのも面倒なのでActionsを使います。

```.github/workflows/maven-publish.yml
name: Publish jl2-web library
on: [ workflow_dispatch ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 11
      uses: actions/setup-java@v1
      with:
        java-version: 11
        server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
        settings-path: ${{ github.workspace }} # location for the settings.xml file
    - name: Build with Maven
      run: mvn -B package --file jl2-web/pom.xml
    - name: Publish to GitHub Packages Apache Maven
      run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml --file jl2-web/pom.xml
      env:
        GITHUB_TOKEN: ${{ github.token }}
```

このYAMLをベースにGitHub ActionsでCI/CDが動作します。`GITHUB_TOKEN`を使うのであれば特別`settings.xml`を管理する必要はないと思われます。

すると以下のようにGitHubリポジトリからリンクが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54904/31264d6b-29ef-7c58-80fd-dce872291f21.png) ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54904/bd18a699-f95c-69e4-1c15-79c333b30142.png)

こちらにデプロイしたライブラリを利用する時は以下のpom.xmlのように依存リポジトリを追加します。

```pom.xml
    <repositories>
        <repository>
            <id>github</id>
            <name>NKLab repository</name>
            <url>https://maven.pkg.github.com/{YOUR_NAME}/{YOUR_PRJ_NAME}</url>
        </repository>
    </repositories>
```

GitHub Actionsと組み合わせて非常に便利なんですが以下の課題があります。

- a) パスワード無しでの公開設定のやり方が分からなかった
- b) 複数のライブラリを一つのリポジトリに入れる時の権限管理

課題というか単にやり方が分からないだけなのですが、aは何となく現時点ではサポートしてないように見えます。bに関しては`Personal access token`等を使えば出来るのは分かるのですが`GITHUB_TOKEN`でのやり方が分からずちょっとペンディング。

GitHub Actionsとインテグレーションされているのは便利ですし認証必須なことも社内ライブラリであれば問題ないので、GitHubを使ってチーム開発している時にはとても便利だと思います。
なお、有料プランと無料プランが選べます。

# Maven Pluginと連携させてGCSにリポジトリを構築する

S3やGCS、Azure Blobのようなオブジェクトストレージに構築する方法です。

- [CloudStorageMaven](https://github.com/gkatzioura/CloudStorageMaven)
- [Maven RepositoryをGCSに構築する](https://blog.orz.at/2019/04/08/gcs-maven/)

完全無料ではありませんがオブジェクトストレージは各社とも十分に安いですしMavenのアカウント管理ではなく各クラウドのIAMで権限管理が出来るので既に使っている人には便利だと思います。
私はGCPを使っていますし、CloudBuildも使ってるのでこれが一番楽ですね。

使い方は簡単で`pom.xml`に以下のようにプラグインというかextentionの設定をします。最新は2.3ですがGCS対応にバグがあるので1.7の使用をお勧めします。

```xml
<distributionManagement>
    <snapshotRepository>
        <id>nklab-snapshot</id>
        <url>gs://{バケット名}/snapshot</url>
    </snapshotRepository>
</distributionManagement>
<build>
    <extensions>
        <extension>
            <groupId>com.gkatzioura.maven.cloud</groupId>
            <artifactId>google-storage-wagon</artifactId>
            <version>1.7</version>
        </extension>
    </extensions>
</build>
```

`url`には任意のバケット名とフォルダ名を記載します。とりあえず私はSnapshotRepositoryには`snapshot`の名前を付けています。`repository`タグを追加する事でもちろんSnapShot以外もデプロイする事ができます。

```xml
<distributionManagement>
    <snapshotRepository>
        <id>my-repo-bucket-snapshot</id>
        <url>gs://mavenrepository/snapshot</url>
    </snapshotRepository>
    <repository>
        <id>my-repo-bucket-release</id>
        <url>gs://mavenrepository/release</url>
    </repository>
</distributionManagement>
```

そして、以下のコマンドでデプロイします。

```bash
mvn -B deploy 
```

この際、権限管理はIAMになるのでGCSにローカルからデプロイしたい場合は以下のようにサービスアカウントの鍵ファイルを環境変数に指定する必要はあります。まあ、GCPではお馴染みの方法ですね。`gcloud auth login –brief`でログインしての認証でも大丈夫です。

```bash
GOOGLE_APPLICATION_CREDENTIALS=~/seacret/mybuild-1632c221dd5c.json mvn -B deploy
```

利用する場合は以下のようにpom.xml依存に追加します。

```xml
<repositories>
    <repository>
        <id>my-repos</id>
        <name>My repository</name>
        <url>https://storage.googleapis.com/{バケット名}/snapshot/</url>
    </repository>
</repositories>
```

CloudBuildなどからビルドする場合はGCS側の設定さえしておけば特に問題はありません。公開設定も含めてGCSの通常の制御と一緒なのでGCPに慣れている人はこの方法が便利だと思います。

# GCP Artifact Registry

GoogleのContainer Registryの後継というか発展版になるサービスです。元々はDocker Containerにしか対応してないのですが、現在α版としてMavenやnodejsも対応しています。

https://cloud.google.com/artifact-registry?hl=ja

こちら、バックエンドがGCSなのですがセキュリティスキャンの自動化など様々な機能も付いていて、個人的に注目しているサービスとなります。私はGCPがメインプラットフォームなのでCloudBuildなど各システムとの相性も良さそうですし。

ただ、こちらは2020/08時点ではα版なので申請しないと利用できません。とりあえず申請してみたのですがまだ試せてない状態です。秋から年末にかけてβとして一般のユーザも利用できるようになる気がします。

# まとめ

Mavenのリポジトリのホスティングは面倒なので地味に悩ましい問題なのですが、最近はOSSを自分でホスティングする以外にも結構選択肢があります。CI/CDを実現するパーツとしても重要なので、この辺をうまく活用して手軽に社内ライブラリや個人ライブラリを共有/公開できるようにしていきたいですね。

それではHappy Hacking!