news 2026/9/18 21:01:41

OkHttp 版本发布流程全指南:从版本号变更、打 Tag 到 Maven Central 自动发布

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OkHttp 版本发布流程全指南:从版本号变更、打 Tag 到 Maven Central 自动发布

OkHttp 版本发布流程全指南:从版本号变更、打 Tag 到 Maven Central 自动发布

【免费下载链接】okhttpA meticulous HTTP client for the JVM, Android, and GraalVM.项目地址: https://gitcode.com/gh_mirrors/okh/okhttp

本文以 OkHttp 仓库的 docs/releasing.md 为骨架,完整讲解该多模块项目的官方发版流程:如何更新 CHANGELOG、如何通过一组sed命令批量替换版本号、如何打 Tag 并切回 SNAPSHOT 开发版本,以及如何借助 GitHub Actions 把制品自动构建并发布到 Maven Central。读完本文,你将能够独立完成一次 OkHttp(或同类 Gradle 多模块项目)的版本发布,并理解版本号在仓库中的权威位置与 CI 发布的底层机制。

一、发布流程总览

OkHttp 的官方发布流程高度脚本化,全部手动操作仅四步:

  1. 更新CHANGELOG.md,记录本次发布的所有变更;
  2. 通过环境变量设置本次发布版本号与下一个开发版本号;
  3. sed批量替换仓库中的版本号、提交并打 annotated Tag,随后把版本号切回-SNAPSHOT开发版本;
  4. 推送 Tag 触发 GitHub Actions,由 CI 自动完成构建、签名与发布到 Maven Central。

整个过程的关键思想是:本地只负责"改版本号 + 打 Tag",制品发布完全交给 CI,避免因本机环境差异导致发布产物不一致。

二、第 1 步:更新 CHANGELOG.md

发布前,维护者需要先更新仓库根目录的 CHANGELOG.md。该文件采用"版本号 + 发布日期 + 变更说明"的结构组织,例如当前仓库中最新记录的Version 5.5.0

## Version 5.5.0 _2026-08-16_ This release introduces **opt-in** support for Encrypted Client Hello (ECH)...
  • 每个版本小节以## Version X.Y.Z开头,紧接着是以下划线包裹的发布日期;
  • 正文按主题介绍新特性、行为变化与重要修复,例如 5.5.0 重点介绍了 ECH 支持与 DNS API 的重大更新;
  • 大版本历史则归档在 docs/changelogs 目录(如changelog_1x.mdchangelog_2x.mdchangelog_3x.mdchangelog_4x.md)。

在写文章时需要注意:CHANGELOG 是用户升级时判断影响面的第一手资料,因此发布前必须把本次版本的所有用户可见变更补全,不能跳过此步骤直接发版。此外,docs/upgrading_to_okhttp_4.md 这类迁移文档也应在涉及破坏性变更时同步更新。

三、第 2 步:设置版本号环境变量

发布脚本使用两个环境变量驱动整个流程:

export RELEASE_VERSION=X.Y.Z export NEXT_VERSION=X.Y.Z-SNAPSHOT

含义如下:

环境变量示例用途
RELEASE_VERSION5.6.0本次正式发布版本号,用于替换 README 与构建脚本中的版本
NEXT_VERSION5.6.1-SNAPSHOT下一个开发版本号,发布提交后立即写入构建脚本

两个变量应放在同一条 shell 会话中执行,以便后续sed命令直接引用。实际执行时把X.Y.Z替换为真实版本号(如5.6.0),NEXT_VERSION通常取5.6.1-SNAPSHOT(补丁递增)或6.0.0-SNAPSHOT(大版本递增)。

四、第 3 步:批量替换版本号、打 Tag、准备下一个版本

这是整个发布流程的核心,原文档给出了一组可直接复用的命令序列。下面逐段拆解其作用,并补充仓库内的实现依据。

4.1 版本号的唯一权威位置:base-conventions

先看第一段命令:

sed -i "" \ "s/version = \".*\"/version = \"$RELEASE_VERSION\"/g" \ build-logic/src/main/kotlin/okhttp.base-conventions.gradle.kts

这条命令把 okhttp.base-conventions.gradle.kts 中所有version = "..."替换为发布版本。这个文件是所有模块共享的基础构建约定,其中第 9–10 行写死了整个仓库的坐标:

group = "com.squareup.okhttp3" version = "5.6.0-SNAPSHOT"

也就是说,OkHttp 的版本号只有一个权威位置build-logic预编译脚本中的version属性。仓库当前正处在5.6.0-SNAPSHOT开发版本,发布时这里会被替换成RELEASE_VERSION,发布完成后再替换回NEXT_VERSION。这种"单一版本源 + 全局约定"的设计,避免了在 20+ 个子模块的build.gradle.kts中逐一维护版本号。各子模块由 settings.gradle.kts 统一纳入构建,例如okhttpokhttp-bomokhttp-tlslogging-interceptormockwebserver3等,它们共享同一个 group 与 version。

注意:sed -i ""是 macOS/BSD sed 的写法(空字符串表示无备份后缀)。在 Linux/GNU 环境下需去掉"",直接使用sed -i "..."

4.2 更新 README 中的依赖坐标

接下来两条命令负责把全仓库所有 README 中的依赖坐标批量升到发布版本:

sed -i "" \ "s/\"com.squareup.okhttp3:\([^\:]*\):[^\"]*\"/\"com.squareup.okhttp3:\1:$RELEASE_VERSION\"/g" \ `find . -name "README.md"` sed -i "" \ "s/\/com.squareup.okhttp3\/\([^\:]*\)\/[^\/]*\//\/com.squareup.okhttp3\/\1\/$RELEASE_VERSION\//g" \ `find . -name "README.md"`
  • 第一条匹配形如"com.squareup.okhttp3:okhttp:5.5.0"的 Gradle/Maven 坐标写法,把版本号替换为$RELEASE_VERSION。例如根目录 README.md 中就有implementation("com.squareup.okhttp3:okhttp:5.5.0")implementation(platform("com.squareup.okhttp3:okhttp-bom:5.5.0"))testImplementation("com.squareup.okhttp3:mockwebserver3:5.5.0")等字样;
  • 第二条匹配形如/com.squareup.okhttp3/okhttp/5.5.0/的路径式坐标写法(如 Maven Central 徽章链接中的路径),同样替换为发布版本;
  • 两条命令都作用于find . -name "README.md"找到的全部 README 文件(根目录及okhttp/okhttp-tls/mockwebserver/samples/等各模块目录下的 README)。

这样用户从任何模块 README 复制的依赖坐标都会指向刚发布的新版本,避免出现"文档写旧版本"的常见问题。

4.3 提交并打 annotated Tag

版本号替换完毕后,执行提交与打 Tag:

git commit -am "Prepare for release $RELEASE_VERSION." git tag -a parent-$RELEASE_VERSION -m "Version $RELEASE_VERSION" git push && git push --tags

值得注意的细节:

  • Tag 名称采用parent-$RELEASE_VERSION的格式(如parent-5.6.0),而不是简单的5.6.0-a参数表示创建annotated Tag(带附注的标签),-m "Version $RELEASE_VERSION"写入附注信息。annotated Tag 会记录打 Tag 者、时间与附注,适合作为发布标记;
  • git push推送提交,再git push --tags推送全部标签。推送 Tag 是触发 CI 发布的关键动作(见第五节)。

4.4 切回 SNAPSHOT 开发版本

发布提交推送完成后,立即把版本号恢复为下一个开发版本:

sed -i "" \ "s/version = \".*\"/version = \"$NEXT_VERSION\"/g" \ build-logic/src/main/kotlin/okhttp.base-conventions.gradle.kts git commit -am "Prepare next development version." git push

注意:这里修改了base-conventions中的version,README 中的依赖坐标保持为已发布的RELEASE_VERSION(文档始终展示稳定版本,开发版本号只存在于构建脚本内部)。这样主分支回到-SNAPSHOT状态继续开发,同时文档面向用户展示的是最新稳定版。

五、第 4 步:等待 CI 构建并发布到 Maven Central

本地操作到此结束,剩下的全部由 CI 自动完成。原文档中的 [GitHub Actions][github_actions] 链接对应本仓库的 .github/workflows/publish.yml 工作流:

name: publish on: push: tags: - '**'

工作流的关键配置如下:

  • 触发条件:任何 Tag 的推送(push: tags: '**'),与本地git push --tags相衔接;
  • 运行环境macos-26,并通过actions/setup-java按仓库中的.java-version文件安装 Temurin JDK;
  • 发布命令./gradlew publish,即执行 Gradle 的publish任务把全部模块发布到 Maven Central;
  • 凭据注入:通过环境变量ORG_GRADLE_PROJECT_*注入三个 Secret ——SONATYPE_CENTRAL_USERNAMESONATYPE_CENTRAL_PASSWORD(Sonatype Central 账号)和GPG_SECRET_KEY(制品签名私钥),Gradle 通过mavenCentralUsername等 project 属性读取。

5.1 发布配置的底层实现

CI 之所以只需一条./gradlew publish就能完成签名与上传,是因为所有模块都应用了 okhttp.publish-conventions.gradle.kts 中的发布约定:

  • 使用com.vanniktech.maven.publish插件,并调用publishToMavenCentral(automaticRelease = true)开启自动发布(上传后无需人工到 Sonatype 控制台点击 Release,自动完成 staging → release);
  • signAllPublications()对全部制品进行 GPG 签名,对应 CI 中注入的GPG_SECRET_KEY
  • POM 元数据(名称、描述、许可证 Apache 2.0、SCM 地址、开发者 Square, Inc.)统一在此配置;
  • okhttp主模块按 Kotlin Multiplatform 配置发布(含 Android/JVM 多平台产物),其余 JVM 模块按KotlinJvm配置;
  • 同时启用binary-compatibility-validator,并对各模块的internal包进行 API 校验忽略设置——发布前会比对api/目录下的 API 基线文件(如 okhttp/api/jvm/okhttp.api),确保没有意外破坏二进制兼容性。

这意味着 CI 不仅要"编译通过",还要通过 API 兼容性校验,才能把okhttpokhttp-bomlogging-interceptorokhttp-tlsmockwebserver3等 20+ 个坐标成功发布到com.squareup.okhttp3组下。整个构建使用 Gradle Wrapper(当前版本为 Gradle 9.6.1,见 gradle/wrapper/gradle-wrapper.properties),保证 CI 与本地构建环境一致。

六、发布后的验证与常见问题

6.1 验证发布结果

发布流程结束后,可从三个层面验证:

  1. Tag 与提交:确认远端存在parent-<版本号>Tag,且主分支最新提交为 "Prepare next development version.";
  2. CI 状态:观察 .github/workflows/publish.yml 对应的运行结果是否全绿;
  3. 制品可解析:按 README.md 中更新后的坐标(如com.squareup.okhttp3:okhttp:<RELEASE_VERSION>)拉取依赖,确认新版本已可被 Gradle/Maven 解析。

6.2 常见问题

  • sed报错sed -i ""是 macOS 语法,Linux 上应改为sed -i;也可改用perl -pi -e保持跨平台一致;
  • README 未全部更新find . -name "README.md"会递归查找所有 README,请确认没有遗漏samples/mockwebserver/等子目录下的文件;
  • 发布失败:多数与凭据相关,检查 CI 中SONATYPE_CENTRAL_USERNAMESONATYPE_CENTRAL_PASSWORDGPG_SECRET_KEY三个 Secret 是否配置且未过期;若 API 校验失败,则需要先更新对应模块api/目录下的.api基线文件再发版;
  • 版本号残留:发布后可用grep -r "version = \"" build-logic确认base-conventions已回到-SNAPSHOT,避免后续开发误用发布版本号。

七、小结

OkHttp 的发布流程可以概括为"文档先行 → 脚本改版本 → Tag 触发 CI → 自动发布"四段式:CHANGELOG 面向用户交代变更,sed命令保证版本号在单一权威位置与全部 README 中同步,annotated Tag 作为发布锚点,而真正的构建、签名与 Maven Central 自动发布则由 publish.yml 与 publish-conventions 全权负责。对于希望在自己的多模块 Gradle 项目(尤其是 Kotlin Multiplatform 项目)上建立类似发布流水线的开发者,这套"单一版本源 + 批量替换 + Tag 驱动 CI"的模式具有很高的参考价值——把重复劳动交给脚本与 CI,把可靠性交给自动化的 API 校验与签名发布。

【免费下载链接】okhttpA meticulous HTTP client for the JVM, Android, and GraalVM.项目地址: https://gitcode.com/gh_mirrors/okh/okhttp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 20:59:06

MySQL Explain执行计划详解:慢查询排查与索引优化实战

凌晨两点被电话叫起来&#xff0c;一条订单查询接口的 P99 从 80ms 直接冲到 4.2s&#xff0c;业务方在群里刷屏。我做的第一件事不是翻代码&#xff0c;而是连上库&#xff0c;把那条 SQL 原封不动复制出来&#xff0c;前面加上 EXPLAIN 敲回车。两秒钟后我看到 typeALL、rows…

作者头像 李华
网站建设 2026/9/18 20:57:22

IDEA打包Web项目war包的完整指南与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 20:55:49

STM32F407ZGT6深度解析:从引脚布局到工业级稳定运行

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 20:55:38

Cursor 改稿降 AI 率,Key 和 Base URL 走 TaoToken 行不行?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 20:55:27

CRC-8校验详解:从多项式原理到DS18B20查表实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 20:55:15

农业无人机喷洒系统闭环控制与硬件选型实战

简介&#xff1a;本资源是一份面向农业工程、植保技术及无人机应用领域学习者与从业者的专业教学课件&#xff0c;聚焦农业植保无人机喷洒系统的核心原理与工程实现。内容系统解析喷洒系统组成&#xff08;继电器、电动泵、压力/离心喷头&#xff09;、水泵选型&#xff08;齿轮…

作者头像 李华