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 仓库

跳过发布

要避免发布项目,在要跳过的子项目中添加以下设置:

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 仓库,还需根据构件选择正确的仓库:SNAPSHOT 版本发布到 central-snapshots 仓库,其他版本发布到本地 staging 仓库。可使用 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 任务将发布到 "local" Ivy 仓库。默认位于 $HOME/.ivy2/local/。同一机器上的其他构建可将该项目列为依赖。例如,若您发布的项目具有如下配置参数:

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

则同一机器上的另一构建可依赖它:

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

您选择的版本号必须以 SNAPSHOT 结尾,或每次发布时更改版本号以表明其为可变构件。

Warning

通常应避免在单机测试之外使用 SNAPSHOT 依赖, 因其会使依赖解析变慢且构建不可重复。

publishLocal 类似,publishM2 任务将发布到用户的 Maven 本地仓库。默认位于 $HOME/.m2/settings.xml 指定的位置或 $HOME/.m2/repository/。另一构建需使用 Resolver.mavenLocal 从中解析:

resolvers += Resolver.mavenLocal

凭据

有两种方式可为此类仓库指定凭据。

第一种且更好的方式是从文件加载,例如:

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

凭据文件是包含 realmhostuserpassword 键的属性文件。例如:

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

第二种方式是内联指定:

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

Note

凭据匹配使用 realmhost 两个键。 realm 键是 HTTP WWW-Authenticate 头的 realm 指令, 是 HTTP 服务器对 HTTP Basic Authentication 响应的一部分。 对于给定仓库,可通过读取收到的所有头来找到。 例如:

curl -D - my.artifact.repo.net

交叉发布

要支持多个不兼容的 Scala 版本,请使用 projectMatrix 和 publish(参见 Cross building setup)。

覆盖发布约定

默认情况下,sbt 会使用您正在使用的 Scala 二进制版本发布构件。例如,若项目使用 Scala 2.13.x,示例构件将发布为 example_2.13。这通常是您想要的,但若发布纯 Java 构件或编译器插件,您需要更改 CrossVersion。详见 Cross building setup 页面的 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)。达到 1.0.0 后遵循常规语义化版本,1.1.0 与 1.0.0 二进制兼容。
  • Some("semver-spec"):语义化版本,所有 0.y.z 视为初始开发(无二进制兼容保证)。
  • Some("pvp"):Haskell 包版本策略,X.Y 视为主版本。
  • Some("strict"):要求版本完全匹配。

此信息将标注到 pom.xml 文件中,便于下游项目判断版本冲突是否可安全解析。参见 Preventing version conflicts with versionScheme (2021)。

修改生成的 POM

publishMavenStyletrue 时,POM 由 makePom 操作生成并发布到仓库而非 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:")
}