自作のAndroidライブラリを手軽に全世界に公開する

# はじめに

最近、Adaptive LayoutというJetpack Compose用のライブラリを公開しました。

https://github.com/takagimeow/adaptive-layout

Androidライブラリの開発と公開を行うことが自分にとっては初めての体験だったため、どのように公開すれば良いのか試行錯誤を繰り返していました。

そんなときに出会ったのがJitPackというサービスです。
このライブラリは、JitPackを使って公開を行なっています。

はじめてAndroidライブラリを公開するにあたり、ものすごく簡単にAndroidライブラリを公開できてしまいました。
この体験をみなさんにもぜひ共有したかったので、今回は忘備録としてまとめてみることにしました。

# JitPackってなに？

Jitpackは、JVMとAndroidプロジェクトのために存在するパッケージリポジトリです。
Gitプロジェクトをオンデマンドでビルドして、すぐに利用可能なアーティファクトと呼ばれる`jar`や`aar`を提供してくれます。

Jitpackでは、プロジェクトをGitHubにプッシュするだけで、ライブラリとして世界中に公開することができるようになっています。もちろん、GitLabやBitBucketでも動作します。

:::note
簡単にいうと、GitHubなどにコミットするだけで、自作のライブラリをAndroidプロジェクトなどでインストール可能にしてくれるサービスということです。
:::

# JitPackを使ってAndroidライブラリを公開してみる

それでは、実際にJitPackの設定を行い、Androidライブラリを公開しようと思います。

:::note warn
今回は、Androidライブラリ自体の作り方については割愛させていただきます。すでにAndroidライブラリを開発している状態で、これから公開しようと考えている方を前提に話を進めていきます。
:::

## 手順1: JitPack Mavenリポジトリを追加する

ルートレベルに存在する**build.gradle**の`repositores`に`maven { url 'https://jitpack.io'`を追加します。

```gradle
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
```

## 手順2: `maven-publish`プラグインを追加する

作成したライブラリのモジュールレベルに存在する**build.gradle**で、`maven-publish`プラグインを追加します。

```gradle
plugins {
    id 'com.android.library'
    id 'maven-publish'
}
```

## 手順3: `afterEvaluate`を追加してアーティファクトを生成できるようにする

先ほど`maven-publish`プラグインを追加したのと同じライブラリの**build.gradle**の最下部に`afterEvaluate {}`を追加します。

```gradle
plugins {
    ...
    id 'maven-publish'
}

group = 'com.github.takagimeow'
version = '1.0'

...

afterEvaluate {
    publishing {
        publications {
            // Creates a Maven publication called "release".
            release(MavenPublication) {
                from components.release
                groupId = 'com.github.takagimeow'
                artifactId = 'adaptive-layout'
                version = '1.0'
            }
        }
    }
}
```

`groupId`は、`com.github.Username`を表します。

`artifactId`は、リポジトリ名を表します。

`version`は、リリースタグ、コミットを表すハッシュ値（コミットハッシュ）、もしくは`ブランチ名-SNAPSHOT`を表します。

コミットハッシュを利用することで、リリース前にライブラリをインストールしてテストすることが可能となります。`ブランチ名-SNAPSHOT`を利用した場合も、そのブランチの最新のコミットがビルドされたアーティファクトをインストールすることが可能になります。

## 手順４: インストール可能かどうかをチェックする

GitHubにコミットして、リリースタグを作成する前に、一度ローカルでインストール可能かどうかを検証してみましょう。

```shell
./gradlew publishToMavenLocal
```

`publishToMavenLocal`を実行して、`BUILD SUCCESSFULL`が表示されると成功です。
この結果、ローカルディレクトリの`$HOME/.m2/repository`にライブラリのアーティファクトが作成されていることが確認できます。

![名称未設定のデザイン (44).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/f7b862e0-e5d2-6647-2754-95a1425a112c.png)

## 手順5: GitHubでリリースを作成する

Android Studioで、タグを作成します。メニューから**Git**そして**New Tag**の順番に選択します。

![名称未設定のデザイン (45).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/2df0f3f0-29e0-1d99-d7aa-f09b68a855e0.png)

タグ名と、メッセージを入力してタグを作成します。

![名称未設定のデザイン (46).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/08faa346-08fe-1a14-b815-ac8c85ca76ab.png)

Android Studioで、**Push**ウィンドウを開きます。

**Push tags**にチェックを入れて、**Current Branch**を選択して**Push**をクリックします。

![名称未設定のデザイン (47).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/a6e46c61-6044-4d95-1edc-5a5de762f9ab.png)

GitHubを確認してみると、新しいタグが作成されていることが確認できます。

![名称未設定のデザイン (48).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/e055fa96-4129-567e-2c48-fe89761a2a5c.png)

そのまま、Releases画面を開いて、タイトルと説明を入力して、リリースを公開します。

![名称未設定のデザイン (49).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/c59dd2bc-704a-1d61-d793-e44b4cd2d014.png)

リリースの作成が完了したら、**JitPack**へアクセスして、リポジトリのURLを入力して検索を行います。

![名称未設定のデザイン (50).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/50d9e285-5faf-89dc-b2b0-15cc87f6b930.png)

ビルドが成功すると、**Log**のアイコンが緑色になります。

![名称未設定のデザイン (51).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/7f57aa23-3c6d-277e-b2a4-bbb89f0d5c3a.png)

# 公開されたライブラリをインストールして使用する

Androidプロジェクトの、ルートレベルに存在する**settings.gradle**に`maven { url 'https://jitpack.io' }`を追加します。

```gradle
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
```

モジュールレベルの**build.gradle**に依存関係を追加します。

```gradle
dependencies {
    implementation 'com.github.takagimeow:adaptive-layout:0.1.2'
}
```

実際に自分が公開しているライブラリを依存関係として追加する場合は、上記の内容を適宜変更してください。

# おまけ

実は、Adaptive Layoutライブラリをリリースしたとき、0.1から0.1.2に至るまでJitPack.io側でのビルドに何度も失敗し続けてしまいました。

その時のログはこちらから確認することができます。

https://jitpack.io/com/github/takagimeow/adaptive-layout/0.1.1/build.log

そのときに、ビルドが成功するまでに行ったこととしては、まず、`maven { url 'https://jitpack.io' }`をルートレベルの**build.gradle**ではなく、**settings.gradle**に設定しました。

```gradle
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
```

**JitPack**のドキュメントなどでは、ルートレベルの**build.gradle**に`allprojects { repositories {} }`の内部に`maven {}`を記載するように説明されているのですが、これを行おうとするとエラーが発生します。

```shell
Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'build.gradle'
```

そのため、エラーを回避するために**settings.gradle**にて設定するようにしています。

Androidプロジェクトを新規作成した後に、ライブラリをモジュールとして追加すると**settings.gradle**の末端に`include`や`rootProject.name`が設定されているのですが、これを公開予定のライブラリのモジュール以外すべて削除しました。

```gradle
// rootProject.name = "My Application"
// include ':app'
include ':adaptivelayout'
```

最初、これらの設定を削除していなかったためビルド時に`* What went wrong:
A problem occurred configuring root project 'My Application'.`というエラーなどが発生していました。

ルートディレクトリに、**jitpack.yml**を追加して、ビルド時に`openjdk 11`を使うように指定しました。

```yml
jdk:
  - openjdk11
```

これらの修正を施した結果、無事ビルドが通り、ライブラリを公開することができました。

https://github.com/takagimeow/adaptive-layout

# まとめ

僕がnpmに初めてパッケージを公開したときには、もっと大変だった思い出があります。なのでその時の記憶の影響で、オープンソース用のライブラリを開発したり公開したりすることに若干の抵抗が今まではありました。

今回初めてAndroidライブラリを公開するにあたって、**JitPack**用のアカウント作成も特に必要なく、GitHubでリリースを作成するだけで公開できてしまったので、本当に素晴らしい開発体験でした。

みなさんも、ぜひ**JitPack**を使って自作ライブラリをどんどん公開してみてください！

# 参考にした記事

https://docs.jitpack.io/intro/

https://www.section.io/engineering-education/how-to-create-and-publish-your-own-android-library/

https://www.talentica.com/blogs/publish-your-android-library-on-jitpack-for-better-reachability/

https://github.com/jitpack/android-example

https://stackoverflow.com/questions/19862682/android-studio-push-tags-to-remote

https://zenn.dev/y_mimura/scraps/d75609a474d35c