自作のScalaライブラリをMaven Central Repositoryにリリースする

# 前置き
先日 [zaim4s](https://github.com/kiris/zaim4s) という Zaim API の Scala Client ライブラリを公開しました。

http://kiris.hatenablog.com/entry/zaim4s

自作のScalaライブラリを公開するにあたって、日本語の情報が意外と少なかったり、情報が古くなってしまっていると感じたので、本エントリーを書きました。
基本的にはSBT公式ドキュメントや、各プラグインのREADMEに書かれている情報を日本語にしてまとめた内容です。

本エントリーは GitHub 上の公開プロジェクトを Sonatype 社の管理する Maven Central Repository に自作のScalaライブラリを公開する手順について解説します。

GitHub 上に私設の Maven Repository を作成してライブラリ公開する場合は、[Play2/Scala向けライブラリを公開する(SBTでGithub上のMavenに)](http://qiita.com/shouta-dev/items/44b1729db39edbb507fd) 等を参照してください。

# 環境

本エントリーを書くのに使用した環境は以下の通りです。

* Max OS X El Capitan 10.11.5
* scala 2.12.2
* sbt 0.13.15
* sbt-sonatype 1.1
* sbt-pgp 1.0.0
* sbt-release 1.0.5



# 事前準備

**この項目の作業は、複数のプロダクトを公開する場合でも最初に一度だけ行なえば良い作業です**

## Sonatype JIRA にアカウントを登録する

Maven Central Repository に公開するためには、Sonatype OSSRH(OSS Repository Hosting) にコードをデプロイする必要があります。
そのためには、 Sonatype JIRA での申請が必要なので、まずは下記のURLから Sonatype JIRA のアカウントを作成しましょう。

https://issues.sonatype.org/secure/Signup!default.jspa

また、後程使用する sbt-sonatype のため、 `$HOME/.sbt/0.13/sonatype.sbt` に以下の設定を記述してください。

```
credentials += Credentials(
    "Sonatype Nexus Repository Manager",
    "oss.sonatype.org",
    "<Sonatype JIRAのユーザー名>",
    "<Sonatype JIRAのパスワード>"
)
```

## sbt-pgp を使ってGPGの公開鍵を keyserver に登録する

Maven Central Repository に公開するファイルは[GPG署名](https://ja.wikipedia.org/wiki/GNU_Privacy_Guard)が必要なので、鍵の作成と keyserver への公開鍵の登録を行ないます。

これらの作業に、今回は [sbt-pgp](https://github.com/sbt/sbt-pgp) を使用します。

まずは sbt-pgp を有効化するため、 `~/.sbt/0.13/plugins/gpg.sbt` に以下の設定を記述してください。

```
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")
```

続いてSBTのコンソールを開き、以下の手順でGPG鍵の作成と公開鍵の登録を行ないます。

```
> set useGpg := true
> set pgpReadOnly := false
> pgp-cmd gen-key

> pgp-cmd list-keys
/Users/kiris/.sbt/gpg/pubring.asc
-------------------------------------
pub     RSA@2048/<Key Id>       2017-06-24
id                              kiris <kiris60@gmail.com>

> pgp-cmd send-key <Key Id> hkp://pool.sks-keyservers.net
```

# プロジェクトの準備

**この項目の作業は、複数のプロジェクトを公開する場合は各プロジェクト毎に必要な作業です**

## Sonatype JIRAにNew Project Issueを作成する

**(追記) Group Idが同一の場合は、複数のプロジェクトで使いまわすことが出来ることをコメント欄にて教わりました。ありがとうございます。**

[Sonatype JIRA](https://issues.sonatype.org/secure/Dashboard.jspa)に事前準備で作成したアカウントでログインして、画面の左上の`"create issue"` からIssueを作成します。

* Issue Type: "New Project"を選択
* Summary: プロジェクトの概要
* Group Id: build.sbtのorganizationの値
* Project Url: プロジェクトのサイトURL（githubのURLで良い）
* SCM Url: gitのURL

以下のURLはzaim4sの記述例です。

https://issues.sonatype.org/browse/OSSRH-32546

しばらくすると、Sonatypeの方からコメントが付くはずです。
英語でのやりとりとなりますが、基本的には定型文のやりとりだけで大丈夫なはずです。


## SBTの設定

Maven Central Repository へのリリースは、[sbt-sonatype](https://github.com/xerial/sbt-sonatype)を使うことでSBT上から行なえるようになります。

プロジェクトの各ファイルに、以下の設定を追加してください。

### *(project root)/project/plugins.sbt*

```
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1")
```
### *(project root)/build.sbt*
**※内容は公開したいプロダクトの内容に合せて書き換えてください。**

```
licenses := Seq("APL2" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt"))
homepage := Some(url("http://example.com"))

publishMavenStyle := true
publishArtifact in Test := false
publishTo := Some(
  if (isSnapshot.value)
    Opts.resolver.sonatypeSnapshots
  else
    Opts.resolver.sonatypeStaging
)

scmInfo := Some(
  ScmInfo(
    url("https://github.com/your-account/your-project"),
    "scm:git@github.com:your-account/your-project.git"
  )
)

developers := List(
  Developer(
    id    = "Your identifier",
    name  = "Your Name",
    email = "your@email",
    url   = url("http://your.url")
  )
)
```

# デプロイとリリース
`sbt publishSigned` を実行することで、Sonatype OSSRH にデプロイすることが出来ます。
この時 `build.sbt` の `version` 項目に `SNAPSHOT` suffixが付いている場合は [Sonatype Snapshots Repository](http://oss.sonatype.org/content/repositories/snapshots/) に公開されます。

[Sonatype Releases Repository](https://oss.sonatype.org/content/repositories/releases/) にライブラリを公開する場合は、
`build.sbt` の `version` から `SNAPSHOT` suffixを外して`sbt publishSigned` を実行し、
続いて `sbt sonatypeRelease` を実行してリリース作業を行ないます。

リリース作業が無事に成功すれば、無事に Releases Repository にライブラリが公開されます。

# (おまけ)リリースの自動化
これまでの手順でライブラリを Maven Central Repository にリリースすることが出来ました。
しかし、[sbt-release](https://github.com/sbt/sbt-release)を使うことで

* テスト
* パッケージング
* リリース
* バージョニング
* Git Repositoryのtag付け

といったリリースプロセスの自動化をすることができておすすめなので、簡単にですがご紹介します。

## SBTの設定
まずはいつも通り、SBT側の設定を行ないます。
sbt-sonatypeの時と同様にプロジェクトの各ファイルに、以下の設定を追加してください。

### *(project root)/project/plugins.sbt*
```
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.5")
```

### *(project root)/version.sbt*
```
version in ThisBuild := "0.1-SNAPSHOT"
```

### *(project root)/build.sbt*

zaim4sでの設定例です。
各コマンドの説明等は[公式のREADME](https://github.com/xerial/sbt-sonatype)を参照してください。

```
import ReleaseTransformations._
releaseProcess := Seq[ReleaseStep](
  checkSnapshotDependencies,
  inquireVersions,
  runClean,
  runTest,
  setReleaseVersion,
  commitReleaseVersion,
  tagRelease,
  ReleaseStep(action = Command.process("publishSigned", _)),
  setNextVersion,
  commitNextVersion,
  ReleaseStep(action = Command.process("sonatypeRelease", _)),
  pushChanges
)
```

## 自動化されたリリース
`sbt release` を実行することで、設定で記述した通りにリリース作業が行なわれます。

お疲れ様でした。

# 参考にしたサイト

* SBT公式ドキュメント - Using Sonatype / http://www.scala-sbt.org/0.13/docs/Using-Sonatype.html
* sbt 0.13.1でMaven Centralリポジトリに登録する方法
 / http://daiksy.blogspot.jp/2014/02/sbt-0131maven-central.html
* GitHub で公開したソースコードを Maven Central Repository に登録する手順 / https://blog.tagbangers.co.jp/ja/2015/02/27/to-register-the-source-code-that-was-published-in-github-to-maven-central-repository