发布到中央仓库

Note

文档中的食谱部分以最少说明聚焦于目标。

向 Central Portal 发布的一般概念,另请参阅 Sonatype 的 Publish guides

目标

我想将项目发布到中央仓库。

步骤

准备 1:Central Portal 注册

请按 Sonatype 的 Publish guides 创建 Central Portal 账户。

  • 若您曾有 OSSRH 账户,请使用 Forgot password 流程将账户迁移到新的 Central Portal,以保留此前的命名空间关联。
  • 若通过 GitHub 认证,io.github.<user_name> 会自动关联到该账户。

请按 register a namespace 指南中的步骤,将域名与您的账户关联。

准备 2:PGP 密钥对

请按 Sonatype 的 GPG guide 生成 PGP 密钥对。

安装 GnuPG,并确认版本:

$ gpg --version
gpg (GnuPG/MacGPG2) 2.2.8
libgcrypt 1.8.3
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>

接下来生成密钥:

$ gpg --gen-key

列出密钥:

$ gpg --list-keys

/home/foo/.gnupg/pubring.gpg
------------------------------

pub   rsa4096 2018-08-22 [SC]
      1234517530FB96F147C6A146A326F592D39AAAAA
uid           [ultimate] your name <[email protected]>
sub   rsa4096 2018-08-22 [E]

分发密钥:

$ gpg --keyserver keyserver.ubuntu.com --send-keys 1234517530FB96F147C6A146A326F592D39AAAAA

步骤 1:sbt-pgp

sbt-pgp 插件 可用 GPG/PGP 为发布的工件签名。(也可选用 sbt-ci-release 自动化发布流程。)

将以下一行加入 project/plugins.sbt,以便在构建中启用:

addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1")

Note

请确保 sbt 可用的 PATH 中包含 gpg 命令。

步骤 2:凭据

在门户中生成用于凭据的用户令牌。令牌须保存在安全位置(不要放在仓库中)。

sbt 2.x 还可读取环境变量 SONATYPE_USERNAMESONATYPE_PASSWORD,并开箱即为 central.sonatype.com 追加凭据,便于在 CI 环境(如 GitHub Actions)中自动发布。

- run: sbt ci-release
  env:
    PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
    PGP_SECRET: ${{ secrets.PGP_SECRET }}
    SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
    SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}

在本机上,常见做法是使用 $HOME/.sbt/2/credentials.sbt 文件,内容如下:

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

接下来创建文件 $HOME/.sbt/sonatype_central_credentials

host=central.sonatype.com
user=<your username>
password=<your password>

步骤 3:配置 build.sbt

要发布到 Maven 仓库,需要配置若干设置以生成正确的元数据。

注意:向 Central Portal 发布时,必须将 publishTo 设为 localStaging 仓库:

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

将这些设置放在 build.sbt 末尾,或单独的 publish.sbt 中:

organization := "com.example.project2"
organizationName := "example"
organizationHomepage := Some(url("http://example.com/"))

scmInfo := Some(
  ScmInfo(
    url("https://github.com/your-account/your-project"),
    "scm:[email protected]:your-account/your-project.git"
  )
)
developers := List(
  Developer(
    id = "Your identifier",
    name = "Your Name",
    email = "your@email",
    url = url("http://your.url")
  )
)

description := "Some description about your project."
licenses := List(License.Apache2)
homepage := Some(url("https://github.com/example/project"))

// Remove all additional repository other than Maven Central from POM
pomIncludeRepository := { _ => false }
publishMavenStyle := true

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

pom.xml 的完整格式(Maven 所用项目配置的产物)见 POM Reference。您可在 build.sbt 中通过 pomExtra 选项添加更多内容。

步骤 4:暂存工件

在 sbt shell 中执行:

> publishSigned

步骤 5:上传或发布 bundle

在 sbt shell 中执行:

> sonaUpload

这会将 bundle 上传到 Central Portal。点击 "Publish" 按钮即可发布到中央仓库。

若要自动化发布,请执行:

> sonaRelease

发布后,工件在中央仓库 https://repo1.maven.org/maven2/ 上可见可能需要十分钟到数小时。