sbt publish

概要

sbt [query / ] publish
sbt [query / ] publishSigned
sbt [query / ] publishLocal
sbt [query / ] publishM2

説明

publish 系タスクはプロジェクトのコンパイルと公開の手段を提供する。この文脈での公開とは、Maven POM や ivy.xml などのディスクリプタと、JAR や war ファイルなどのアーティファクトをリポジトリにアップロードし、他のプロジェクトがライブラリ依存性として指定できるようにすることである。

  • publish タスクはプロジェクトを JFrog Artifactory や Sonatype Nexus などのリモートリポジトリに公開する。
  • publishSigned タスクは sbt-pgp プラグイン で有効化され、GPG 署名付きアーティファクトの公開に使用する。
  • publishLocal タスクはプロジェクトを Ivy のローカルファイルリポジトリ(通常は $HOME/.ivy2/local/)に公開する。同一マシン上の他のプロジェクトからこのプロジェクトをライブラリ依存性として利用できる。
  • publishM2 タスクはプロジェクトをローカル Maven リポジトリに公開する。

Central Repo への公開 に関してはレシピ参照。

公開のスキップ

公開を避けるには、スキップしたいサブプロジェクトに以下のセッティングを追加する:

publish / skip := true

一般的な用途はルートプロジェクトの公開を防ぐことである。

リポジトリの定義

リポジトリを指定するには、publishTo にリポジトリを割り当て、必要に応じて公開スタイルを設定する。例えば Nexus にアップロードする場合:

publishTo := Some("Sonatype Snapshots Nexus" at "https://oss.sonatype.org/content/repositories/snapshots")

ローカル Maven リポジトリに公開する場合:

publishTo := Some(MavenCache("local-maven", file("path/to/maven-repo/releases")))

ローカル Ivy リポジトリに公開する場合:

publishTo := Some(Resolver.file("local-ivy", file("path/to/ivy-repo/releases")))

Central Repository に公開する場合、アーティファクトに応じて適切なリポジトリを選択する必要がある。SNAPSHOT バージョンは central-snapshots リポジトリへ、それ以外のバージョンはローカルのステージングリポジトリへ公開する。この選択は version セッティングの値を使って行える:

publishTo := {
  val centralSnapshots = "https://central.sonatype.com/repository/maven-snapshots/"
  if version.value.endsWith("-SNAPSHOT") then Some("central-snapshots" at centralSnapshots)
  else localStaging.value
}

ローカルへの公開

publishLocal タスクは、デフォルトでは $HOME/.ivy2/local/ である「ローカル」の Ivy リポジトリに公開する。同一マシン上の他のビルドがこのプロジェクトをライブラリ依存性として指定できる。例えば、公開するプロジェクトに以下のような設定がある場合:

organization := "com.example"
version := "0.1-SNAPSHOT"
name := "hello"

同一マシン上の別のビルドで以下のように依存関係として指定できる:

libraryDependencies += "com.example" %% "hello" % "0.1-SNAPSHOT"

選択するバージョン番号は SNAPSHOT で終わるか、変更されるアーティファクトであることを示すため公開のたびにバージョン番号を変更する必要がある。

警告

SNAPSHOT ライブラリ依存性の使用は、単一マシン内でのテスト以外は避けるべきである。 ライブラリ依存性の解決が遅くなり、ビルドの再現性が失われるためだ。

publishLocal と同様に、publishM2 タスクはユーザーの Maven ローカルリポジトリに公開する。場所は $HOME/.m2/settings.xml で指定されるか、デフォルトでは $HOME/.m2/repository/ である。別のビルドから解決するには Resolver.mavenLocal が必要である:

resolvers += Resolver.mavenLocal

認証情報

リポジトリの認証情報を指定する方法は2つある。

推奨される方法はファイルから読み込むことである。例:

credentials += Credentials(Path.userHome / ".sbt" / ".credentials")

認証情報ファイルは realmhostuserpassword をキーとするプロパティファイルである。例:

realm=Sonatype Nexus Repository Manager
host=my.artifact.repo.net
user=admin
password=admin123

2つ目の方法はインラインで指定することである:

credentials += Credentials("Sonatype Nexus Repository Manager", "my.artifact.repo.net", "admin", "admin123")

Note

認証情報のマッチングは realmhost の両方のキーを使って行う。 realm キーは HTTP の WWW-Authenticate ヘッダーの realm ディレクティブで、 HTTP Basic Authentication に対する HTTP サーバーのレスポンスの一部である。 リポジトリごとに、受信した全ヘッダーを読むことで確認できる。 例:

curl -D - my.artifact.repo.net

クロス公開

互換性のない複数の Scala バージョンをサポートするには、projectMatrix と publish を使用する(クロスビルドの設定 を参照)。

公開規約のオーバーライド

デフォルトでは sbt は使用中の Scala のバイナリバージョンでアーティファクトを公開する。例えばプロジェクトが Scala 2.13.x を使用している場合、example アーティファクトは example_2.13 として公開される。多くの場合これで十分だが、純粋な Java アーティファクトやコンパイラプラグインを公開する場合は CrossVersion を変更する必要がある。詳細はクロスビルドの設定Publishing convention セクションを参照。

公開されるアーティファクト

デフォルトでは、メインのバイナリ JAR、ソース JAR、API ドキュメント JAR が公開される。他の種類のアーティファクトを公開する宣言や、デフォルトのアーティファクトの無効化・変更が可能である。詳細はArtifactを参照。

バージョンスキーム

versionScheme セッティングはビルドのバージョンスキームを追跡する:

versionScheme := Some("early-semver")

サポートされる値は "early-semver""pvp""semver-spec""strict" である。sbt はこの情報を pom.xmlivy.xml にプロパティとして含める。

  • Some("early-semver"): 0.Y.z 内のパッチ更新(例: 0.13.0 と 0.13.2)でバイナリ互換性を保つ Early Semantic Versioning。1.0.0 以降は通常の Semantic Versioning に従い、1.1.0 は 1.0.0 とバイナリ互換である。
  • Some("semver-spec"): すべての 0.y.z を初期開発として扱う Semantic Versioning (バイナリ互換性の保証なし)。
  • Some("pvp"): X.Y をメジャーバージョンとして扱う Haskell Package Versioning Policy。
  • Some("strict"): バージョンの完全一致を要求する。

この情報は pom.xml に注釈として追加され、下流プロジェクトがバージョン競合を安全に解決できるか判断するのに役立つ。Preventing version conflicts with versionScheme (2021)を参照。

生成される POM の変更

publishMavenStyletrue の場合、makePom アクションで POM が生成され、Ivy ファイルの代わりにリポジトリに公開される。いくつかのセッティングを変更することで POM ファイルを編集できる。pomExtra に XML(scala.xml.NodeSeq)を設定すると、生成される pom に直接挿入される。例:

pomExtra := <something></something>

pomPostProcess セッティングもあり、書き込み前に最終的な XML を操作できる。型は Node => Node である。

pomPostProcess := { (node: Node) =>
  ....
}

makePom は宣言した Maven 形式のリポジトリを POM に追加する。pomRepositoryFilter を変更してフィルタリングでき、デフォルトではローカルリポジトリを除外する。ローカルリポジトリのみを含める場合:

pomIncludeRepository := { (repo: MavenRepository) =>
  repo.root.startsWith("file:")
}