argius note

プログラミング関連

Maven Central に Gradle+macOSで公開 (2018年3月時点)

ようやくMaven Centralに公開したのでメモ。 基本的にはググればだいたい分かることですが、いくつか古い情報や分かりにくいところがあったので、その辺を中心に書いていきます。

URLなどは拙作のMinestraを例にしています。 https://github.com/argius/minestra


環境

一部のバージョンはあまり関係ないとは思いますが、念のため書いておきます。

作業の流れ

準備の手順は、時間がかかるものがあるので、事前にやっておくと良いです。

公開は、Sonatype OSS Repository Hosting (以降、OSSRHと記載)を使って行います。
Nexus Repository Managerを使って、OSSRHのリポジトリーを操作します。

  • 準備
    • Sonatypeアカウント(OSSRH、JIRA共通)
    • GPG認証ツールのインストールとキー作成
    • build.gradleにsigningとuploadArchivesの設定追加
    • ワークスペースのプロジェクトをリリースするバージョンにする
    • (任意)公開したライブラリーをdependencyとして参照するプロジェクトを作成
  • 初回
    • JIRAチケット作成
    • チケット応答:グループIDに関する確認コメント
      • チケットコメントに回答
    • Gradle uploadArchivesタスク実行
    • Nexus Repository Manager リポジトリー"Close"
    • Stagingテスト
    • Nexus Repository Manager リポジトリー"Release" or "Drop"
    • チケットにリリース完了をコメント
      • チケット応答:自動化の完了通知
    • 公開
  • 2回目以降

準備

Sonatypeアカウント

JIRAアカウント取得の申請をします。ここは特に問題ないです。
OSSRH共通のアカウントになります。

GPG認証ツールのインストールとキー作成

GPG KeyChainを使いました。
キーを作成し、KeyStoreにアップロードしておきます。

それと、後述のsigningプラグインで使用するsecretKeyRingFileのsecring.gpgは、このバージョンでは自動で作成されないので、手動でエクスポートします。

gpg --export-secret-keys -o ~/.gnupg/secring.gpg

build.gradleにsigningとuploadArchivesの設定追加

署名とアーカイブアップロードのために、それぞれプラグインsigningmavenを使用します。

まず、プラグインのパラメーターをGradleの設定ファイルに書いておきます。

  • ~/.gradle/gradle.properties
org.gradle.daemon=true
signing.keyId=(使用するGPGキーのID)
signing.password=(使用するGPGキーのパスワード)
signing.secretKeyRingFile=($HOMEを記載)/.gnupg/secring.gpg
sonatypeUsername=(Sonatypeアカウントのユーザー名)
sonatypePassword=(Sonatypeアカウントのパスワード)

daemonはデフォルトでtrueの気がしますが、とりあえず書いておきます。)

build.gradleの設定は、基本的には下記ページの通りに記載すればOK。

Deploying to OSSRH with Gradle (The Central Repository - Sonatype) http://central.sonatype.org/pages/gradle.html

ただし、これをそのまま適用すると、他のタスクを実行した時もossrhUsername/ossrhPasswordを参照するようになってしまい、これらが設定されていない環境でbuildなどのタスクを実行する際にエラーになってしまいます。

以下のように、プロパティーの有無をチェックして変数を宣言するように書き換えれば、エラーを回避できます。
なお、参考にした記事の関係で、ossrhUsername/ossrhPasswordsonatype~に書き換えています。

uploadArchives {
  repositories {
    mavenDeployer {
      def sonatypeUsername = project.hasProperty("sonatypeUsername") ? project.property("sonatypeUsername") : ""
      def sonatypePassword = project.hasProperty("sonatypePassword") ? project.property("sonatypePassword") : ""

      beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }

      repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
        authentication(userName: sonatypeUsername, password: sonatypePassword)
      }

      snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
        authentication(userName: sonatypeUsername, password: sonatypePassword)
      }
// 以下略

ワークスペースのプロジェクトをリリースするバージョンにする

説明するまでもありませんが、アップロードコマンドを実行する前にbuild.gradleversionプロパティーをリリースしようとしているバージョンになっているかどうかを確認します。

公開したライブラリーをdependencyとして参照するプロジェクトを作成

公開しようとしているライブラリーを参照するプロジェクトを作成します。MavenやGradleなどでビルドできるようになっていればOK。
既存のプロジェクトでも大丈夫ですが、作業中でないプロジェクトが良いでしょう。

この手順はスキップすることが可能ですが、これを作っておけばStagingのライブラリーを公開する前にチェックができますのでできれば作っておきましょう。

公開手順・初回

チケット作成〜アップロード可能まで

新規プロジェクトの申請を行うためのJIRAチケットを作成します。ここは参考サイトの通りですがざっと書いておきます。

JIRA - Sonatype https://issues.sonatype.org

JIRAにあらかじめ取得しておいたSonatypeアカウントでログインし、メニューバーにあるCreateボタンを押すと、Project: "Community Support ~"、Issue Type: "New Project"というチケットの入力フォームが表示されます。

ここに必須入力(赤字の*の項目)に入力して作成すればOK。必須でないところはデフォルトのままにしておきましょう。
Summaryにはプロジェクトの簡単な説明を入力します。私は"Minestra utilities project"としました。

Group IdはJavaのパッケージの時と同様のドメイン名による命名(Reverse Domain Name Notation)を使用します。ドメインを持っていない場合はcom.github.(YourGithubAccount)を使うことができます。私の場合はcom.github.argiusですね。
Group Idについては、フォームにも記載されていますが、下記ページを読んでおくと良いでしょう。

http://central.sonatype.org/pages/choosing-your-coordinates.html

チケット作成後、Group Idに使用したドメイン名の所有者かどうかの質問コメントが付きますので、妥当であれば"Yes"とコメントで回答します。

その後、Nexus Repository Managerへのアップロードの準備ができたことの通知がコメントされます。

JIRAのやり取りははっきりとした所要時間が分かりませんので、気長に待ちましょう。

アップロード〜Stagingテスト

アップロードタスクを実行します。

# Gradle Wrapperの例
$ ./gradlew uploadArchives

成功した場合でも、下記のようなエラーがでます。
参考サイトにも同様の報告がありますが、無視して良いようです。

Could not find metadata net.argius:minestra/maven-metadata.xml in remote (https://oss.sonatype.org/service/local/staging/deploy/maven2/)

Nexus Repository Managerへログインし、アップロードしたライブラリーが登録されていることを確認します。

Nexus Repository Manager https://oss.sonatype.org

対象のリポジトリーにチェックを入れて"Close"ボタンを押します。ダイアログが表示されますので、Confirmボタンを押して確定させます。 Staging(下記URL)にアップロードされたことを確認します。

https://oss.sonatype.org/content/groups/staging/

(例:Minestraの場合は、https://oss.sonatype.org/content/groups/staging/net/argius/minestra/

次に、Stagingのテストを行います。
このライブラリーを参照するプロジェクトのリポジトリー参照先URLをStagingのものに変更します。Gradleの場合は下記。 あとはbuildなりtestなりのタスクを実行すればテストできます。

repositories {
    // jcenter()
    maven { url "http://oss.sonatype.org/content/groups/staging/" }
}

リリース〜公開

再度Nexus Repository Managerで先ほどと同じリポジトリーをチェックして、今度は"Release"ボタンを押してConfirmします。 テストが失敗して破棄したい場合は"Drop"ボタンを押します。

今度はpublicに公開されますので、アップロードを確認します。 https://oss.sonatype.org/content/groups/public/

(例:Minestraの場合は、https://oss.sonatype.org/content/groups/public/net/argius/minestra/

確認できたら、JIRAチケットにアップロードが完了した旨をコメントします。
しばらくすると、チケットに"Central sync is activated"というコメントが来ます。これでMaven Centralへの同期設定が完了したので、時間が来ればMaven Centralへ反映されます。
コメントによると10分で反映されるとのこと。初回は測っていませんが、2回目の実測では15分でした。

しばらく待ってから、下記のリポジトリーに登録されていることを確認します。 https://repo1.maven.org/maven2/

(Minestraの場合は、https://repo1.maven.org/maven2/net/argius/minestra/

これで初回の公開は完了です。

ここまでが全て正常に終わったら、チケットはCloseしておきましょう。

2回目以降

一度公開まで完了するとアップロード設定と同期設定が継続して利用可能になりますので、2回目以降はJIRAチケットに関わる部分を除いて初回と同じです。

参考URL

Deploying to OSSRH with Gradle (The Central Repository - Sonatype) http://central.sonatype.org/pages/gradle.html

Maven Central Repositoryでパッケージを公開する - エンジニアっぽいことを書くブログ https://ishiis.net/2016/12/29/maven-central/

GradleでMaven Centralにライブラリを公開する - たごもりすメモ http://tagomoris.hatenablog.com/entry/2016/02/16/114226

(おわり)