今回は、GitHubで開発したライブラリをMaven Central Repositoryで公開するまでの道のりをまとめてみました。
全部無料です!(笑)
公開までのプロセス
- JIRAのアカウントを作成する
- JIRAでIssueを発行し、ライブラリの登録申請をする
- GitHubでソースコードを開発する
- GPGで秘密・公開鍵を作成して、公開鍵をKeyServerに登録する
- GPGの秘密鍵でJarに署名して、OSSRHにリリース(デプロイ)する
- OSSRHからCentralへ、ライブラリがリリース(ステージング)される
登場人物は以下の通りです。
name | description |
---|---|
開発者 | 私、もしくは私たち |
GitHub | ライブラリのソースコードを管理する場所 |
Maven Central Repository | ライブラリを公開したい場所 |
Sonatype OSSRH | Centralへ公開するために使用するリポジトリホスティングサービス |
Sonatype JIRA | OSSRHにライブラリを登録するための申請をするサイト |
Public KeyServer | OSSRHにライブラリを登録する際の署名鍵を管理するサーバ |
以降で、順を追ってプロセスを紹介していきます。
Step.1 JIRAのアカウントを作成する
何はともあれ、ライブラリ公開の申請をするためにユーザ登録をします。
JIRAで「Sign Up」リンクを押下すると、以下のように登録画面が表示されます。
JIRAのアカウントを作ります。
ここで付与するUsername
はJIRAでしか使わないので、それほど気を使う必要はないと思っています。
Step.2 JIRAでIssueを発行し、ライブラリの登録申請をする
次に、登録したユーザでライブラリ公開の申請をします。
JIRAにログインして「Create」ボタンを押下すると、以下のようにIssueを作成できます。
だいたい見たままですが、必須項目のSummary、GroupId、Project URLとSCM URLを入れればOKです。
ちなみにここで入力するGroupIdはドメインルートで、例えばライブラリにio.github.yoshikawaa.webapp
みたいなGroupIdを付与していても、io.github.yoshikawaa
で申請すればOKでした。つまり、一度申請してしまえば、ライブラリごとに申請しなおす必要はないってことですね。(間違ってたら中の人が教えてくれると思いますw)
なお、Issueを発行してから承認されるまで、通常2~3日くらいのようです。
さて、ここで問題は以下になります。
- GroupId(つまりライブラリのルートパッケージ名)を決める必要がある
- 実際に開発しているソースコードのリポジトリが必要である
ということで、実際にIssueを作成するのは、ソースコードを開発してからになります。
Step.3 GitHubでソースコードを開発する
当たり前ですが、まずは先立つソースコードを開発しましょう。
ソースコードを開発する上でのポイントは以下のとおりです。
- ソースコード品質を確保する
- JavaDoc & ソースコードのJarを作成する
- ドメイン(ルートパッケージ名)を取得する
- 適切なライセンスを付与する
- Centralの要件に合わせて、POMを設定する
Step.3.1 ソースコード品質を確保する
オープンソースでライブラリを開発して公開する以上、CI(継続的インテグレーション)によりソースコード品質を確保しなければ。ということで、GitHubには連携するCIサービスがいくつもあるので、Marketplaceからテーマごとに適当にピックアップして使います。
ちなみに私は、以下のようなセットを使っています。
theme | service |
---|---|
回帰テスト | Travis CI |
カバレッジ | Codacy |
コードレビュー | Codacy |
Step.3.2 JavaDoc & ソースコードのJarを作成する
公開するならJavaDocくらい書きましょう!
MavenプラグインでJavaDocとソースコードのJarを作成すれば、一緒にデプロイして公開することができます。
Mavenプラグインを使用するには、POMにちょっとプラグインの設定を足すだけです。
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<configuration>
<show>protected</show>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
ちなみに私は、ライブラリの拡張ポイントを示すため、protected
メソッドまでJavaDocに出力しています。
Step.3.3 ドメイン(ルートパッケージ名)を取得する
ここまで思うまま開発してきましたが、問題が一つ。
ライブラリのGroupIdとライブラリのルートパッケージ名は通常揃えると思いますが、
Javaのパッケージ名のお作法として、サイトのドメインを逆にする(google.com
なら、com.google.~
)というのがあります。
残念なことに、私は個人サイトを持っていないし、自分でサーバを借りたりドメインを取得する気もないので、しゃーなし、適当につけるか。。。と思っていたところ、作れます!そう、GitHubならね。
GitHubにはリポジトリからサイトを作成できるGitHub Pagesという機能があり、[ユーザ名].github.ioという名前でリポジトリを作成してテーマを選択するだけで、お手軽に自分のサイトが作れます。
architectテーマを選択すると、こんなデザインのページが作成されました。
写真はある程度コンテンツを書いた後なので、デフォルトページとはちょっと違います。
ちなみにGitHub PagesではデフォルトでJekyllという静的サイトジェネレータを使用しており、MarkDownで書いたコンテンツを自動的にHTMLに変換してくれます。
ということで、ライブラリのGroupIdはio.github.[ユーザ名].~
にしました。
※まー、実際にはcom.github.[ユーザ名].~
でも良かったんですが…
Step.3.4 適切なライセンスを付与する
オープンソースで開発する上ではライセンスに気を使う必要があります。
種類ばかり豊富なオープンソースライセンスからどれを選ぶべきかを調べるのは面倒なので、偉大な先駆者の方々の力を借ります。
@tukiyo3さんの記事がまとまってて参考になりました。
ライセンスについては、以下の3点の対応をすることにしました。
- リポジトリにライセンス文章のファイルを置いて、トップページからリンクする
- ソースコードにライセンス文章を付与する
- デプロイするJarにライセンス文章のファイルを入れる
まずはGitHubの機能を利用して、ライセンス文章のファイルを置きました。
新規ファイル作成でLICENSE
という名前をつけると、
作成するライセンスの種類を選ぶことができます!
なお、今回は後付けでライセンス文章のファイルを作りましたが、リポジトリ作成時に選択することもできます。
次に、License Maven Pluginを利用して、ソースコードにライセンス文章を入れました。
プラグインの使い方は@kazuki43zooさんの記事が分かりやすいので、ここでは省略します。
最後に、Maven Resources Pluginを利用して、Jarにライセンス文章のファイルを入れました。
※ここまでする必要があるかはさておき…
Step.3.5 Centralの要件に合わせて、POMを設定する
Centralのガイドを参考に設定していきます。
licenses
、developers
、scm
あたりを追加する必要がありました。
Step.4 GPGで秘密・公開鍵を作成して、公開鍵をKeyServerに登録する
OSSRHでは、デプロイ時のユーザ認証に加えて、GPG(GNU Privacy Guard)による署名を利用して、アップロードされたJarの正当性を確認しています。
GPGによる署名を利用するには、
- GPGで秘密・公開鍵を作成して、公開鍵をKeyServerに登録する
- GPGの秘密鍵でJarに署名する
というプロセスを踏む必要があります。
KeyServerへの登録まではGPGソフトで行い、Jarへの署名はMavenプラグインで行います。
WindwosでGPGを扱うなら、GUIソフトのGpg4winが便利だと思いますが、
最終的にMavenプラグインからはコマンドラインでgpg.exeを呼び出す必要があり、Gpg4win(GUI)で作成・管理した鍵がgpg.exe(コマンドライン)に連携されなかったため、結局コマンドラインで鍵を管理しました。
コマンドラインでの鍵の作成・管理とKeyServerへの登録は@moutendさんの記事が分かりやすいので、ここでは省略しますが、登録先はUbuntuのSKS OpenPGP Public Key Server(keyserver.ubuntu.com
)になります。
Step.5 GPGの秘密鍵でJarに署名して、OSSRHにリリース(デプロイ)する
ここからはMavenでの作業になります。settings.xmlとPOMに、署名とデプロイのための設定を入れます。
- pom.xml
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<name>Sonatype Nexus Releases</name>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
</distributionManagement>
Maven GPG Pluginを利用して、作成したJarにGPGで署名します。
また、デプロイ先としてOSSRHのスナップショットおよびリリースリポジトリを設定します。
- settings.xml
<settings>
<servers>
<server>
<id>ossrh</id>
<username><!-- JIRAのアカウント名 --></username>
<password><!-- JIRAのパスワード --></password>
</server>
</servers>
<properties>
<gpg.executable>gpg.exe</gpg.executable>
<gpg.keyname><!-- キーサーバに登録した鍵名 --></gpg.keyname>
<gpg.passphrase><!-- 鍵作成時に付与したパスワード --></gpg.passphrase>
</properties>
</settings>
OSSRHのユーザ認証のため、JIRAアカウントの情報を設定します。ここで重要なのは、POMのdistributionManagement
に記載したリポジトリのIDとsettings.xmlに記載するserver
のIDを合わせることです。異なっているとアカウントの情報が連携されません。
また、GPGプラグインで使用するGPGの実行ファイルパス、使用する鍵名およびパスワードを設定します。なお、パスワード以外は省略することもできます。
ここまで設定したら、あとはデプロイするだけです!
$ mvn clean deploy
ちなみに、GitHubからソースコードをCloneしてビルドしたいだけの人が署名エラーになったりするのはウザいので、プロパティを指定してGPGプラグインの実行をスキップすることもできます。
Step.6 OSSRHからCentralへ、ライブラリがリリース(ステージング)される
基本的には、待っていればOSSRHからCentralにリリースされるらしいです。
待てない人はOSSRHにログインして自分でリリースしたり、nexus-staging-maven-pluginでリリースすることが可能です。
まとめ
公式リファレンスと先駆者の方々の情報が充実しており、割と楽にOSSRHへのリリースまで進むことができました。
ちなみに、Sonatype JIRAへの登録など面倒だという方は、GitHubリポジトリをMavenリポジトリにする(@narikeiさんの記事)などいくつか方法があるので、模索してみると良いと思います。