Android アプリ用ライブラリの AAR パッケージを Maven Central で公開する方法
AAR パッケージを Maven Central に公開している人は結構いるけど、build.gradle をどういう感じに書けばいいのかわかりづらかったので書き残しておきます。
使用するリポジトリとビルドツール
Sonatype OSS Maven Repository の使用について
Maven Central Repository にパッケージを公開する方法の 1 つに、Sonatype OSS Maven Repository にパッケージを公開し、それを Maven Central Repository に同期するという方法があります。 これは Apache による Maven Central への公開方法のガイドにも書かれています。
- Apache による Maven Central への公開方法のガイド: Maven - Guide to uploading artifacts to the Central Repository
多くの場合、Maven Central への公開には Sonatype OSS Maven Repository を使うのが簡単で良いでしょう。
Sonatype OSS Maven Repository へのアップロードと Maven Central Repository への同期
基本的な流れ
次のガイドを見るとある程度詳細に書かれていますので、この記事では詳しく説明しません。
1. 「Introduction」 から 6. 「Central Sync Requirement」 までは書かれている通りに作業したり、単に読んだりするだけで良いです。 実質的に必要な作業は、Sonatype JIRA アカウントを作って、JIRA チケットを作成する、ということと、GPG クライアントをインストールし、GPG キーを作成して公開鍵を配布するというぐらいのはずです (GPG 鍵周りの話は後述します)。 JIRA チケットを作ってから実際にリポジトリにアップロードできるようになるまでに 2 日ほどかかりますので、ソースコードの方の準備ができてなくても、JIRA チケットを作る作業は先に進めておくといいかもしれません。 ちなみに私が android-lib-ZXingCaptureActivity のリリースをしたときに作った JIRA チケットは次のものです。
難しいのは 7. の箇所ですね。 パッケージを作成して、Sonatype OSS Maven Repository にアップロードします。 Maven を使う場合や Ant を使う場合などの説明があり、Gradle についても 7d. 「Stage Releases with Gradle」 にて次のページが紹介されています。
JAR をリリースするのであればここを参考にすればよいでしょう。 AAR をリリースする場合の方法は後で説明します。
アップロードした artifact は、(リリースバージョンの場合) 最初は Staging Repository になります。 これをリリースするためには、8a. に書かれている手順に従って web 上で操作して、Staging Repository を close し、それから release します。 さらに、初回のリリースの場合は、9. に書かれているように JIRA チケットにコメントを行い、Maven Central への同期を有効化してもらう必要があります。 (同期は 2 時間程度ごとに行われるようです。)
GPG クライアントをインストールし、GPG キーを作成して公開鍵を配布する
するべきことは、Maven Central に公開する成果物に署名するための GPG キーを生成して、公開鍵を配布することです。 方法は次のページに書かれています。
まず、GnuPG をインストールします。 次に、次のコマンドで鍵ペアを生成します。
gpg --gen-key
そして、公開鍵を次のコマンドで配布します。 keyid (下の例だと C6EED57A) は適切に置きかえてください。
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys C6EED57A
Gradle で AAR パッケージを生成して Maven リポジトリにアップロードする方法
AAR パッケージをアップロードするための build.gradle の設定を説明していきます。
Maven リポジトリへの公開方法としては maven-publish プラグイン もありますが、ここでは uploadConfigurationName
タスク と maven プラグイン の組み合わせを使用します。
uploadConfigurationName
タスクについて
uploadConfigurationName
タスクは、Gradle の標準プラグインのひとつである base プラグインで提供されるものです。 Android Gradle プラグインを使用する場合は、自動的にこのプラグインが適用されるようです *1。
uploadConfigurationName
タスクは、その名のとおり、ConfigurationName のコンフィギュレーションに属する artifact をビルドし、ビルド結果をアップロードするタスクです。 例えば archives
コンフィギュレーションに属する artifact をビルドしてアップロードするために、uploadArchives
というタスクを使用できます。
archives
コンフィギュレーションについて
依存ライブラリなどを管理するためのコンフィギュレーションの仕組みが Gradle にはあるわけですが、アップロードする artifact の管理にもコンフィギュレーションが使用されます。 Java プラグインによってプロジェクトで生成される JAR が含まれるデフォルトのコンフィギュレーションが archives
です。 同様に、Android Gradle プラグインで生成される AAR パッケージも、デフォルトで archives
コンフィギュレーションに含まれます。
自分でコンフィギュレーションを定義して、そこに AAR パッケージを含めるようにしてもいいのですが、特にそうする理由がなければ、この archives
コンフィギュレーションをそのまま使えばいいでしょう。
Javadoc の JAR と sources の JAR を作成するタスクを定義し、それらの JAR を archives
configuration に追加する
Maven Central に公開する場合は、Javadoc を固めた JAR とソースコードを固めた JAR もアップロードする必要があります。 そのため、この 2 つの JAR を生成するタスクを定義し、それらの JAR を archives
コンフィギュレーションに含めるようにする必要があります。
release
variant で Javadoc JAR と sources JAR を作ればいいと思いますので、私は次のようにタスクを定義しました。
android.libraryVariants.all { variant -> if (variant.name == 'release') { def javadocTaskName = "javadoc${variant.name.capitalize()}"; task(javadocTaskName, type: Javadoc) { description "Generates Javadoc for ${variant.name}." source = variant.javaCompile.source destinationDir = reporting.file("${variant.name}-docs") ext.androidJar = "${android.plugin.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar" classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) } task("javadocsJar${variant.name.capitalize()}", type: Jar) { classifier = "javadoc" from tasks[javadocTaskName].destinationDir } task("sourcesJar${variant.name.capitalize()}", type: Jar) { classifier = "sources" from variant.javaCompile.source } /* artifacts management. * See: http://www.gradle.org/docs/current/userguide/artifact_management.html */ artifacts { archives tasks["javadocsJar${variant.name.capitalize()}"] archives tasks["sourcesJar${variant.name.capitalize()}"] } } }
もうちょっときれいに書ければ嬉しいのですが、なかなか難しそうです。
これ以降は AAR でも JAR でも大差ないのですが、一通り説明しておきます。
Maven の POM 情報を記述する
Maven プラグインを使って、uploadArchives
の設定として POM の情報を記述します。
ここで記述されたプロジェクト名などを元に POM が生成されます。 以下のような感じになります。
apply plugin: 'maven' version = "1.0-SNAPSHOT" // Maven のバージョン規約で、開発中のものには “-SNAPSHOT” を付ける ext.isReleaseVersion = !version.endsWith("SNAPSHOT") group = "org.example.android.sugoi.project" uploadArchives { repositories.mavenDeployer { // 後からここに署名のための記述やリポジトリの URL の記述などを行う pom.artifactId = 'sugoi-library' pom.project { name 'Sugoi library' packaging 'aar' description 'This is Sugoi library' url 'http://sugoi.android.example.org/' scm { url 'scm:git@github.com:yourname/sugoi-library.git' connection 'scm:git@github.com:yourname/sugoi-library.git' developerConnection 'scm:git@github.com:yourname/sugoi-library.git' } licenses { license { name 'The Apache License, Version 2.0' url 'http://www.apache.org/licenses/LICENSE-2.0.txt' distribution 'repo' } } developers { developer { id 'yourname' name 'Your Name' email 'yourname@example.org' } } } } }
署名やアップロード先の記述
あとは、signing プラグインを使って署名するようにする設定と、アップロード先の Maven Repository の設定を書けば完了です。
- signing プラグイン: Chapter 53. The Signing Plugin
次のような記述になります。
apply plugin: 'maven' apply plugin: 'signing' signing { required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") } sign configurations.archives } uploadArchives { repositories.mavenDeployer { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } def sonatypeRepo = isReleaseVersion ? "https://oss.sonatype.org/service/local/staging/deploy/maven2/" : "https://oss.sonatype.org/content/repositories/snapshots/" repository(url: sonatypeRepo) { authentication(userName: sonatypeUsername, password: sonatypePassword) } // ... }
signing プラグインで署名するためには、次のように Gradle プロパティを設定しておく必要があります。 ここで指定する keyId などは、「GPG クライアントをインストールし、GPG キーを作成して公開鍵を配布する」 の箇所で生成した鍵のものです。
signing.keyId=24875D73 signing.password=secret signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg
また、sonatypeRepo にアクセスするためのユーザー名とパスワードを、次のように Gradle プロパティで設定する必要があります。
sonatypeUsername=your_username sonatypePassword=your_password
Gradle プロパティは、プロジェクトや Gradle のホームディレクトリ (デフォルトでは USER_HOME/.gradle) に gradle.properties というファイルを作ってそこに記述することができますし、Gradle コマンドの -P オプションで指定することもできます *2。
- Gradle プロパティについて: Chapter 14. Tutorial - 'This and That'
参考文献
- ONGOING DEV: Publish an aar file to Maven Central with Gradle : AAR を Gradle で生成して Maven Central にアップロードする方法について。 javadoc と sources の JAR 生成について書かれていない。 全体の流れもあってわかりやすいと思う。
- Vandal Software • Publishing an Android Library (AAR) to a Maven Repository : AAR を Gradle で生成して Maven Central にアップロードする方法について。 javadoc と sources の JAR 生成について書かれていない。 また、この記事のように configurations を設定すると POM がおかしくなる。 全体の流れは書かれていない。
- Pushing AARs to Maven Central | Chris Banes : Gradle を使って AAR を Maven Central にアップロードする方法の選択肢が 4 つ挙げられている。
- GradleでMaven Central Repositoryに成果物をリリースする - GeekFactory : AAR じゃなくて JAR の場合について書かれた日本語の記事。
- u1aryzの備忘録とか: githubをMavenリポジトリとしてAndroidライブラリプロジェクト(aar)をデプロイして使用する : Maven Central じゃない場所へのアップロード。