javachanges GitHub Actions 发布流程使用指南
1. 概述
这个仓库现在已经接入了一套基于 javachanges 自身命令的 GitHub Actions 发布流程。
这份文档是当前仓库自举发布流程的专用说明。如果你想看更通用的 GitHub Actions 接入方式,请继续看 GitHub Actions Usage Guide。
目标流程如下:
- 功能分支合并到
main main上如果存在.changesets/*.md- GitHub Actions 自动生成或更新 release PR
- release PR 合并后
- GitHub Actions 可以在
snapshot分支上自动发布 snapshot - GitHub Actions 自动打 tag、发布到 Maven Central、创建 GitHub Release
1.1 工作流流程图
2. 工作流组成
仓库包含四条工作流:
| 文件 | 作用 |
|---|---|
.github/workflows/ci.yml | 常规 CI,验证 Java 8 构建和发布 profile |
.github/workflows/release-plan.yml | 在 main 上扫描 changesets,自动生成 release PR |
.github/workflows/publish-snapshot.yml | 把 snapshot 分支当前构建发布到配置好的 snapshot 仓库 |
.github/workflows/publish-release.yml | 在 release PR 合并后执行正式发布 |
3. release PR 工作流
release-plan.yml 的核心逻辑是:
mvn -B -DskipTests exec:java -Dexec.args="github-release-plan --directory $GITHUB_WORKSPACE --write-plan-files false --execute true"它会:
| 动作 | 说明 |
|---|---|
读取 .changesets/*.md | 收集待发布变更 |
| 计算发布版本 | 生成 releaseVersion 和 nextSnapshotVersion |
| 应用发布计划 | 更新 <revision> 和 CHANGELOG.md,不提交生成的 plan 文件 |
| 删除已消费的 changeset | 避免重复发布 |
工作流随后会把这些变更提交到:
changeset-release/main并自动创建或更新 PR。
4. snapshot 发布工作流
publish-snapshot.yml 会在 snapshot 分支 push 和手动 workflow_dispatch 时运行。
它会依次做这些事:
- 校验 snapshot 仓库变量和凭据
- 为本次 workflow 生成稳定的 snapshot build stamp
- 执行
javachanges preflight --snapshot - 执行
javachanges publish --snapshot --execute true
最终发布的不是根 1.3.1-SNAPSHOT 原样坐标,而是类似:
1.3.1-20260420.154500.abc1234-SNAPSHOT当前仓库的 workflow 默认使用:
<github.run_id>.<github.run_attempt>.<git short sha>作为构建标识,所以即使同一 commit 重跑,也能在 snapshot 分支上得到可区分的 snapshot 版本。
snapshot 发布需要配置这些 GitHub Actions secrets:
| 类型 | 名称 | 是否必需 |
|---|---|---|
| Secret | MAVEN_CENTRAL_USERNAME | 是 |
| Secret | MAVEN_CENTRAL_PASSWORD | 是 |
| Secret | MAVEN_GPG_PRIVATE_KEY | 是 |
| Secret | MAVEN_GPG_PASSPHRASE | 是 |
当前仓库的 snapshot workflow 已切换为使用 central-publishing-maven-plugin 配合 -SNAPSHOT 版本直接上传,不再依赖单独的 maven-snapshots server id 和 distributionManagement 认证入口。
workflow 成功后,建议通过下面这些 snapshot 地址验证:
https://central.sonatype.com/repository/maven-snapshots/https://central.sonatype.com/repository/maven-snapshots/io/github/sonofmagic/javachanges/<resolved-snapshot-version>/maven-metadata.xmlhttps://central.sonatype.com/repository/maven-snapshots/io/github/sonofmagic/javachanges/<resolved-snapshot-version>/javachanges-<timestamped-version>.jar
需要注意的是,hosted snapshot 仓库根地址不能直接浏览目录,所以验证时应优先看 metadata URL、具体产物 URL,或者直接用 Maven / Gradle 做一次依赖解析。
5. 正式发布工作流
publish-release.yml 现在有两种运行模式:
- release PR 合并后自动触发
- 需要对某个已经合并的 release commit 重新发布时,通过
workflow_dispatch手动触发
自动触发模式只会在以下条件全部满足时运行:
| 条件 | 说明 |
|---|---|
| PR 已 merged | 必须是真的合并,不是关闭 |
base branch 是 main | 只发布主线 |
head branch 是 changeset-release/main | 只处理 release PR |
它会依次做这些事:
- checkout release PR 的 merge commit
- 执行
github-tag-from-plan --execute true - 执行
github-release-from-plan,生成target/release-notes.md并导出releaseVersion - 用
central-publishprofile 发布到 Maven Central - 执行
github-release-from-plan --execute true,创建或更新 GitHub Release
5.1 正式发布重试行为
Publish Release 可以安全地针对同一个 release merge commit 重跑。
如果上一次运行已经创建了 release tag,但在 Maven Central 发布或 GitHub Release 创建前失败,请用同一个 release merge commit SHA 重跑 Publish Release。当 GitHub Release 还不存在、远端 tag 又指向这个 commit 时,github-release-publish-state 会继续执行;随后 github-tag-from-plan 会把已存在的 tag 当成可恢复状态,而不是重新创建。
如果远端 tag 已存在但指向另一个 commit,workflow 会在发布前失败。此时应先检查这个 tag,确认后要么用被 tag 的 commit 重跑 workflow,要么在确认旧 tag 指向错误后再移动 tag。
在 actions/setup-java 导入私钥之后,当前两个发布 workflow 都会先执行 javachanges ensure-gpg-public-key。这一步会:
- 读取当前导入的签名指纹
- 尝试把公钥上传到
hkps://keyserver.ubuntu.com和hkps://keys.openpgp.org - 轮询确认至少一个受支持的 keyserver 已经能查询到该公钥
这样可以避免 Maven Central 在后续校验签名时出现类似 Invalid signature for file ... Could not find a public key by the key fingerprint 的失败。
6. 仓库必须配置的 Secrets
你需要在 GitHub 仓库的 Settings > Secrets and variables > Actions 中配置:
| Secret | 用途 |
|---|---|
MAVEN_CENTRAL_USERNAME | Sonatype Central Portal token username |
MAVEN_CENTRAL_PASSWORD | Sonatype Central Portal token password |
MAVEN_GPG_PRIVATE_KEY | ASCII armored GPG 私钥 |
MAVEN_GPG_PASSPHRASE | GPG 私钥口令 |
publish-release.yml 现在会在准备 Java、Maven settings 和 GPG 之前先校验这些 secrets。只要有任意一个缺失,工作流会立刻失败,并直接指出缺的是哪一个 secret。
针对已经失败的 Publish Release 运行,推荐恢复步骤是:
- 把缺少的 secrets 补齐
- 如果之前失败日志里提到公钥指纹不可发现,先使用当前仓库版本重新触发,让 workflow 自动发布并校验公钥
- 在 Actions 页面重新触发
Publish Release - 确认它能进入
Publish to Maven Central这一步
7. 推荐使用方式
日常开发时:
- 新建分支
- 修改代码
- 添加 changeset
- 提交并发起 PR
- 合并到
main
添加 changeset 的示例:
mvn -q -DskipTests compile exec:java -Dexec.args="add --directory $PWD --summary 'add GitHub Actions release automation' --release minor"这条命令现在会写出官方 package-map 风格的 changeset 文件,例如:
```md
---
"javachanges": minor
---
add GitHub Actions release automation
```8. 版本模式说明
为了支持 release PR 合并后再发布正式版,当前仓库已经切换到:
<version>${revision}</version>并通过:
<revision>1.0.0-SNAPSHOT</revision>维护开发版本。
这样 release PR 合并后:
| 阶段 | 版本 |
|---|---|
| 发布版本 | 通过 manifest-field --fresh true 推导,例如 1.0.0 |
| 主干版本 | 已提前推进到下一个快照,例如 1.0.1-SNAPSHOT |
publish workflow 会在真正部署时使用:
-Drevision=<releaseVersion>从而发布正式版,而不会把快照版上传到 Central。
snapshot workflow 则会使用:
-Drevision=<baseVersion>-<snapshotBuildStamp>-SNAPSHOT这样同一个开发 snapshot 线可以连续发布多个唯一构建,而不会都挤在同一个可见版本名下。
在当前仓库里,推荐的开发路径是:
- 正式发布相关变更先合并到
main - 想触发对外 snapshot 发布的变更合并到
snapshot - 由
publish-snapshot.yml从snapshot分支头部自动发布
9. 手动触发
如果你需要手动重跑某条流程,可以在 GitHub Actions 页面触发:
| 工作流 | 是否支持 workflow_dispatch |
|---|---|
Release Plan | 是 |
Publish Snapshot | 是 |
Publish Release | 是,需要把 release_commit_sha 设为 release PR 合并后的 commit |
如果某个已经 merge 的 release PR 触发过失败的 Publish Release,通常不需要重新走一遍 release PR。直接手动触发 Publish Release,并把原始 merge commit SHA 通过 release_commit_sha 传进去即可。
10. 发布前本地验证
在本地,你可以先验证这个自举流程是否正常:
mvn -B verify
mvn -B -Pcentral-publish -Dgpg.skip=true verify
mvn -B -DskipTests compile exec:java -Dexec.args="status --directory $PWD"
mvn -B -DskipTests compile exec:java -Dexec.args="preflight --directory $PWD --snapshot --snapshot-build-stamp local.dev.001"11. 总结
现在这个仓库的标准发布路径是:
| 阶段 | 入口 |
|---|---|
| 日常校验 | CI workflow |
| snapshot 发布 | Publish Snapshot workflow |
| 生成 release PR | Release Plan workflow |
| 正式发布 | Publish Release workflow |
如果你需要可复用到其它仓库的 GitHub Actions 模板和命令拆分,请继续看 GitHub Actions Usage Guide。