量産型エンジニアの憂鬱

きっと僕は何物にもなれない。

Mavenライブラリ配布の自動化をやめた話

この記事は モバイル 自動化/自動テスト Advent Calendar 2017 の19日目です。

皆さんは、JavaやKotlinで作成したライブラリ、加えてGradleプラグインの配布について悩んだことはないでしょうか。
クロスプラットフォームな開発環境も増えましたが、Android開発といえば Java や Kotlin といった JVM言語が主流です。
もちろんライブラリもこれらの言語で作成されます。 

一般的に、JavaやKotlinで作成されたライブラリの配布はMavenリポジトリを介して行われます。

Maven公式のリポジトリMaven Central です。 その他、 Bintray jcenter も有名なリポジトリです。 よってライブラリを作成して公開したい場合は上記サーバーにデプロイすることになります。 しかし、Maven Central にライブラリを登録するまでにはアカウント作成など面倒な手順を踏むことになります。

今は21世紀なのでサクッとライブラリを作成して公開したいですね。

Mavenリポジトリを立てて公開する

Mavenリポジトリは、誰でも立てることができます。 http(s) でアクセスできるサーバーを立てるだけです。

自分はこれまで、GitHubソースコードを管理し、レンタルサーバーリポジトリを立てて公開していました。 また、ソースコードの更新からリポジトリへの公開は自動化していました。

自分の場合、MavenリポジトリとJenkinsサーバーを同一にしています。 GitHubで master ブランチが更新された場合、 Jenkinsが mvn deploy を実行するだけです。 このコマンドではローカルのMavenリポジトリに配置されますが、 HTTPサーバーの静的コンテンツを配置するディレクトリ以下にMavenリポジトリを指定すると、 サーバーを介してライブラリを利用することができます。

<distributionManagement>
    <repository>
        <id>local</id>
        <name>local</name>
        <url>file://localhost/path/to/DocumentRoot</url>
    </repository>
</distributionManagement>

この方法ではライブラリを作るたびにJenkinsのジョブを追加しなければなりません。 また、公開できるサーバーとドメインを所有している必要があります。

そこで、GitHubのみを利用して公開する方法を探していました。

GitHub Pagesを利用して公開する

GitHubの ユーザー名.github.io リポジトリあるいは特定のブランチを maven リポジトリとして公開しちゃう方法です。 「GitHub Maven リポジトリ」で検索とこの方法がヒットします。

今回は ユーザー名.github.io リポジトリを利用して公開する方法をご紹介します。

  1. GitHub上に、ユーザー名.github.io リポジトリを作成する

  2. public_repo と user:email の権限を付与した Personal Access Token を作成する

  3. ローカルマシンの settings.xml でサーバーを設定する
    通常は $HOME/.m2/settings.xml にあります。

<settings ...>
  <servers>
    <server>
     <id>github.com</id>
     <password>取得した Personal Access Token</password>
    </server>
  </servers>
</settings>
  1. プロジェクトの pom.xml を設定する
    今回利用する site-maven-pluginMaven Plugin として提供されているので、pom.xml で設定しています。
  <profiles>
    ...
    <profile>
      <id>github</id>
      <properties>
        <!-- settings.xml で記述したサーバーの id -->
        <github.global.server>github.com</github.global.server>
      </properties>
      <distributionManagement>
        <repository>
          <id>internal.repos</id>
          <name>Temporary Repository</name>
          <!-- mvn deploy コマンドで ビルドディレクトリ/mvn 以下にデプロイするようにする -->
          <url>file://${project.build.directory}/mvn</url>
        </repository>
      </distributionManagement>
      <build>
        <plugins>
          <plugin>
            <groupId>com.github.github</groupId>
            <artifactId>site-maven-plugin</artifactId>
            <version>0.12</version>
            <configuration>
              <message>Maven artifacts for ${project.version}</message>
              <!-- GitHubにプッシュするディレクトリを ビルドディレクトリ に指定する -->
              <outputDirectory>${project.build.directory></outputDirectory>
              <!-- ビルドディレクトリには classファイル なども作成されるのでディレクトリを指定する -->
              <includes>
                <!-- mvn deploy コマンドで作成されるローカルリポジトリ -->
                <include>mvn/**/*</include>
              </includes>
              <repositoryOwner>GitHubのユーザー名</repositoryOwner>
              <repositoryName>GitHubのユーザー名.github.io</repositoryName>
              <branch>refs/heads/master</branch>
              <!-- デフォルトだと最新版の artifact で上書きしてしまうので、マージする -->
              <merge>true</merge>
            </configuration>
            <executions>
              <execution>
                <goals>
                  <goal>site</goal>
                </goals>
                <!-- maven deploy 後に実行されるようにする -->
                <phase>deploy</phase>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
  1. 実行する
    実行時は上述の pom.xml で設定したプロファイルを指定します。
mvn deploy -P github
  1. 自動的に実行されるようにする
    あとはお好みの CI/CD で上述のコマンドが実行されるようにするだけです。

これによりライブラリの配布もGitHub上でできるようになりました。 ライブラリを利用する場合はリポジトリのURLとして https://ユーザー名.github.io/mvn/ を指定します。

maven-site-plugin を利用しているため、Gradleの場合は pom.xml の生成など手間が増えます。

JitPackを利用する

JitPack は少し変わったMavenリポジトリです。 Spockなどがこのリポジトリを介して配布されています。

JitPack を利用する場合、配布側でビルドする必要がありません。 JitPack上のライブラリをインポートしたタイミングで JitPack上でビルドされるのです。

GitHub上のライブラリを利用する

  1. Mavenリポジトリとして https://jitpack.io を指定する

  2. ライブラリの指定

    1. groupId を com.github.リポジトリオーナー名 にする
    2. artifactId を リポジトリ名 にする
    3. バージョンに リリースタグ または コミットハッシュ を指定する

この方法では特別ビルドを行う必要がありません。 しかし、JitPack が groupIdartifactId を書き換えてしまうので、混乱するかもしれません。 ライブラリの groupIdartifactId を それぞれ com.github.リポジトリオーナー名リポジトリ名 にしてしまうのが最も簡単でしょう。 しかし、groupId は独自のドメインを指定したい場合もあります。

JitPackでは DNS TXTレコード を利用してドメイン名を指定する方法を提供しています。 https://jitpack.io/docs/#custom-domain-name

まとめ

最近までレンタルサーバーMaven リポジトリを立てていたのですが、 できる限り管理するサーバーは減らしたいですよね。

Spockを利用する際に指定されていた Mavenリポジトリ が今まで利用したことがなかったものなので調べてみると、 とても便利だったので久しぶりにテンションがあがりました。

これまでGolangJavaScriptRubyなど比較して Javaのライブラリ配布は面倒な印象がありました。 しかし、JitPack を利用すれば配布するためのビルドする必要すらなくなりました。 また、GitHubにソースが公開されているけど配布されていないライブラリについても利用できる可能性があります。

Publicなライブラリの場合はこういったサービスを無料で利用することができて非常に便利ですね。