☰
Deis v1 软件版本发布流程全解析:bumpver 版本工具、CHANGELOG 生成与打 Tag 实操指南
2026/10/10 9:05:11 网站建设 项目流程
  • 后端
  • 云原生

【免费下载链接】deis

Deis v1, the CoreOS and Docker PaaS: Your PaaS. Your Rules.

项目地址:https://gitcode.com/gh_mirrors/de/deis
点击查看免费下载

本文以 Deis v1(CoreOS + Docker PaaS)仓库中维护者发布清单 docs/roadmap/releases.rst 为主体,完整拆解 Deis 补丁版本与主次版本的发布流程:如何用 Go 编写的 bumpver 工具批量更新散落在源码、文档与 Dockerfile 中的语义化版本号、如何用 generate-changelog.sh 从提交日志生成 CHANGELOG、如何提交并推送 release tag,以及发布后对 master 分支和外部渠道的收尾动作。读完后你可以独立走完一次 Deis 产品版本的发布操作,并理解每个版本号在仓库中的分布位置与一致性校验方法。

发布清单的定位与适用前提

releases.rst 是一份面向维护者的 Release Checklist,目标只有一个:协助维护者创建一次新的 Deis 产品版本,并明确要求“流程有变时同步更新本文档”。清单要求从上到下顺序执行,跳过不适用的章节。整个流程围绕三类版本动作展开:

  • Patch Release(补丁发布):从上一个 release tag 检出,cherry-pick 特定修复提交,打补丁 tag;
  • Major or Minor Release(主次版本发布):直接基于 master 分支发布,涉及 milestone 管理、-dev版本后缀替换等额外动作;
  • Any Release(任意版本通用的收尾步骤):CI 构建触发、安装脚本更新、文档站点发布、IRC 频道公告等。

当前仓库正处于 v1 维护期(见 docs/roadmap/roadmap.rst 中“Deis v1 Maintenance”一节,v1 已转入维护,主要跟踪上游 CoreOS 版本升级与安全补丁),仓库内各处版本号一致地停留在1.13.4,本文的示例值均以此为准。

bumpver:批量更新版本号的 Go 命令行工具

清单中所有版本号更新都通过./contrib/bumpver/bumpver完成。该工具位于 contrib/bumpver/ 目录,是一个 Go 编写的单文件命令行程序:入口 bumpver.go 仅一行os.Exit(Command(nil)),全部逻辑在 bump.go 中。

命令语义与参数

从 bump.go 中的 docopt usage 字符串可以看到完整命令规格:

Usage: bumpver [-f <current>] <version> <files>... Options: -f --from=<current> An explicit version string to replace. Otherwise, use the first semantic version found in the first file.
  • -f <current>:显式指定要被替换的旧版本字符串。发布流程中几乎总是显式指定,因为旧版本可能形如1.13.3或1.13.3-dev这类与“第一个匹配到的 semver 不同”的字符串;
  • <version>:新版本号,bump.go 用正则(\d{1,3}\.\d{1,3}\.\d{1,3})校验,不是合法的三段式语义版本会直接报错退出;
  • <files>...:一个或多个待更新文件,工具会替换每个文件中的全部出现位置(bytes.Replace(src, from, []byte(version), -1)),每成功处理一个文件打印一行Bumped <file>。

当未提供-f时,工具从第一个文件中查找首个 semver 匹配作为“旧版本”;若某个文件中找不到匹配则打印Skipped <file>并跳过。这种“显式 from + 全量替换”的设计,使得一次调用可以同时覆盖.go、.py、.rst、.md、Dockerfile 和 user-data 等多种文件——bump_test.go 中的TestGo、TestPython、TestReStructuredText、TestUserdata等用例正是按文件类型逐一验证替换结果,还包含TestBadSemver确认非法版本号(如1.5、0.13.0-dev作为目标版本、latest)会被拒绝。构建与测试通过 contrib/bumpver/Makefile 执行make test build。

Patch Release 场景:全量文件清单

发布补丁版本时,清单要求对完整文件清单执行版本更新(A.B.C→A.B.D)。原始命令如下,其中文件列表完整保留自 releases.rst:

$ ./contrib/bumpver/bumpver -f A.B.C A.B.D \ README.md \ builder/rootfs/Dockerfile \ builder/rootfs/usr/local/src/slugbuilder/Dockerfile \ builder/rootfs/usr/local/src/slugrunner/Dockerfile \ client/deis-version \ contrib/utils.sh \ contrib/coreos/user-data.example \ controller/deis/__init__.py \ controller/Dockerfile \ database/Dockerfile \ deisctl/client/client.go \ deisctl/deis-version \ docs/_includes/_get-the-source.rst \ docs/installing_deis/install-deisctl.rst \ docs/installing_deis/install-platform.rst \ docs/managing_deis/upgrading-deis.rst \ docs/reference/api-v1.7.rst \ docs/troubleshooting_deis/index.rst \ logger/image/Dockerfile \ logspout/image/Dockerfile \ publisher/image/Dockerfile \ registry/Dockerfile \ router/Dockerfile \ store/base/Dockerfile \ version/version.go

对照当前仓库可以确认这些文件确实承载版本号:

文件版本承载方式
version/version.goconst Version = "1.13.4",deisctl 通过--version打印(见 deisctl.go 引用该包)
controller/deis/__init__.py__version__ = '1.13.4'
client/deis-version、deisctl/deis-version纯版本号文本文件,各一行1.13.4
deisctl/client/client.gorefresh-units命令 usage 中的默认 tag[default: v1.13.4]
contrib/utils.shexport DEIS_RELEASE=1.13.4
contrib/coreos/user-data.example安装命令install.sh \| sh -s 1.13.4与DEIS_RELEASE=v1.13.4
各组件 Dockerfile(如 builder/rootfs/Dockerfile、controller/Dockerfile)ENV DEIS_RELEASE 1.13.4镜像标签
文档(docs/installing_deis/install-deisctl.rst、docs/managing_deis/upgrading-deis.rst 等)安装/升级示例中的版本号

需要说明的是,清单中的builder/rootfs/usr/local/src/slugbuilder/Dockerfile与slugrunner路径在维护期仓库中已不存在(builder 相关构建脚本收敛到了 builder/src/ 下的 Go 源码)。这正是清单开头“流程有变时请更新本文档”的要求所在:发布清单是一份“活的”文档,文件列表需要随代码库演进而修剪。

Patch Release 完整流程

补丁发布的每一步都对应 releases.rst 中 “Patch Release” 一节,按序执行:

  1. 检出上一个 release tag:

    $ git checkout vA.B.C

    注意补丁版本不是从 master 发出的,而是从旧 tag 检出后叠加修复,保证补丁基线与上一发布版本完全一致。

  2. cherry-pick 指定的修复提交:

    $ git cherry-pick <commit-ish>...
  3. 执行上文的全量 bumpver 命令,把A.B.C全部替换为A.B.D。

  4. 手动更新 CHANGELOG:清单特别指出,generate-changelog.sh 只统计 merge 提交(git log --merges,见 脚本第 27 行),而 cherry-pick 产生的是普通提交,因此补丁版本必须手工把变更补录进 CHANGELOG.md。

  5. 全库搜索确认无遗漏:

    $ git grep A.B.C

    如果还能搜出旧版本号字符串,说明有文件漏改。

  6. 提交并推送 tag:

    $ git commit -a -m 'chore(release): update version to vA.B.D' $ git tag vA.B.D $ git push --tags origin vA.B.D

Major or Minor Release 发布流程

主次版本直接基于 master 发布,比补丁发布多出 milestone 管理、双阶段版本号替换和 Dockerfile 后缀处理:

  1. 将未完成的 issue 移到下一个 deis milestone,然后关闭当前 milestone。

  2. 检出并更新 master:

    $ git checkout master && git pull
  3. 双阶段版本号替换。master 上的开发版本带-dev后缀(如1.14.0-dev),而发布文档里引用的是稳定版本号A.B.C,因此要分两次执行 bumpver:

    # 第一步:带 -dev 后缀的开发版本号文件,直接指向新版本 $ ./contrib/bumpver/bumpver -f A.B.D-dev A.B.D \ client/deis-version \ controller/deis/__init__.py \ deisctl/deis-version \ docs/reference/api-v1.7.rst \ version/version.go # 第二步:稳定版本号引用的文件(文档、脚本、user-data 等) $ ./contrib/bumpver/bumpver -f A.B.C A.B.D \ README.md \ contrib/utils.sh \ contrib/coreos/user-data.example \ docs/_includes/_get-the-source.rst \ docs/installing_deis/install-deisctl.rst \ docs/installing_deis/install-platform.rst \ docs/managing_deis/upgrading-deis.rst \ docs/troubleshooting_deis/index.rst

    这个两阶段设计与 deisctl/client/client.go 的RefreshUnits实现直接相关:deisctl refresh-units从 Deis 项目的 GitHub 仓库按 tag/SHA 下载 unit 文件(units 包),其 usage 字符串底部有一个默认 tag。清单要求手动把该默认值从[master]改为[vA.B.D],使deisctl默认拉取本次发布的 unit 文件。当前仓库中该默认值即为 client.go 第 276 行 的[default: v1.13.4]。

    另需手工处理:在所有项目 Dockerfile中执行 find-and-replace,把A.B.D-dev镜像标签替换为A.B.D(bumpver 的替换语义无法区分-dev后缀与纯版本号的两种语境,所以这一步留在人工)。

  4. 用脚本生成 CHANGELOG:

    $ ./contrib/util/generate-changelog.sh vA.B.C | cat - CHANGELOG.md > tmp && mv tmp CHANGELOG.md

    即把新生成段拼接到现有 CHANGELOG 前部,然后把标题里的HEAD改为新版本vA.B.D,删除空小节并校对。

  5. git grep A.B.C检查遗漏,然后提交、推送 master、打 tag 并推送 tag:

    $ git commit -a -m 'chore(release): update version to vA.B.D' $ git push origin master $ git tag vA.B.D $ git push --tags origin vA.B.D

CHANGELOG 是怎么生成的

generate-changelog.sh 是整个发布流程中唯一自动化的文档环节,理解它的行为才能解释清单中的那些限制。其核心逻辑:

  • 输入区间:main函数接收FROM(上次 release tag)与TO(默认HEAD),输出以### $FROM -> $TO开头的 markdown 段,与 CHANGELOG.md 现有的### v1.13.3 -> v1.13.4标题格式完全对应;
  • 只统计 merge 提交:retrieve函数执行git log --oneline --merges --format="%h %H %b" --grep="$1" "$FROM".."$TO",这依赖 Deis 的 PR merge 提交信息规范;
  • 按提交类型分组:TYPES变量默认值为feat(;Features fix(;Fixes docs(;Documentation chore(;Maintenance),即按 conventional commit 前缀(feat/fix/docs/chore)把提交归入 Features、Fixes、Documentation、Maintenance 四个####小节;
  • 输出格式:每条记录形如- `c63ade6` Godeps,deisctl: serialize a unit test...,其中子系统名从type(subsystem): message中解析(脚本第 18-21 行);
  • 可定制性:REPOROOT(提交链接前缀,默认为 Deis 官方仓库地址)与TYPES都可通过环境变量覆盖。

--merges过滤正是补丁版本必须手工补录 CHANGELOG 的原因——cherry-pick 提交没有对应的 merge 记录,脚本“看不见”它们。

Any Release:发布后的通用收尾步骤

无论补丁还是主次版本,tag 推送之后都要执行 releases.rst “Any Release” 一节:

  1. 新组件发布:如果本次版本引入了新组件,需先配置test-acceptanceCI 作业将其推送到 Docker Hub。
  2. 手动触发 CI 构建(在 Deis 的 CI 服务器上,指定新的vA.B.Dtag),顺序有严格要求:
    • build-deis-cli-installer-darwin
    • build-deis-cli-installer-linux
    • build-deisctl-installer-darwin
    • build-deisctl-installer-linux
    • 等上述客户端作业全部完成后,再触发test-acceptance验收作业。
  3. 更新 deis.io 仓库中的安装脚本(deis-cli/install.sh与deisctl/install.sh),使其指向新版本A.B.D——这与仓库内 docs/installing_deis/install-deisctl.rst 中curl -sSL http://deis.io/deisctl/install.sh | sh -s 1.13.4一类安装命令保持联动。
  4. 更新 ReadTheDocs 上已发布的文档版本:登录管理后台,把当前版本加入已发布版本列表、从列表中移除最旧版本、重新构建所有已发布版本以刷新各版本页面间的“Versions”索引链接。
  5. 更新 #deis IRC 频道话题,引用新版本号。

发布之后:master 分支的跟进动作

tag 推送完成并不等于发布结束,master 分支还需要一轮收尾,补丁与主次版本的做法不同。

补丁版本发布后

把 master 上的版本号提到刚发布的版本(只针对稳定版本文档引用,不含 Dockerfile 镜像标签):

$ ./contrib/bumpver/bumpver -f A.B.C A.B.D \ README.md \ contrib/utils.sh \ contrib/coreos/user-data.example \ docs/_includes/_get-the-source.rst \ docs/installing_deis/install-deisctl.rst \ docs/installing_deis/install-platform.rst \ docs/managing_deis/upgrading-deis.rst \ docs/reference/api-v1.7.rst \ docs/troubleshooting_deis/index.rst $ git commit -a -m 'chore(release): update version in master to vA.B.D' $ git push origin master

随后在 GitHub Releases 页面创建 release notes:正文直接粘贴新加入的 CHANGELOG.md 段落,必要时加一段说明性文字(例如引用安全修复或升级注意事项)。

主次版本发布后

  • 把 deisctl/client/client.go 中RefreshUnits的默认 tag 从[vA.B.D]改回[master],让 master 分支恢复跟踪主干 unit 文件;

  • 把 master 版本号 bump 到下一个计划版本并加-dev后缀:

    $ ./contrib/bumpver/bumpver -f A.B.D A.B.E-dev \ client/deis-version \ controller/deis/__init__.py \ deisctl/deis-version \ version/version.go

    同时在所有项目 Dockerfile 中把A.B.D替换为A.B.D-dev,提交并推送 master(提交信息形如chore(release): update version in master to vA.B.D-dev);

  • 在 deis.io 的博客上按既有格式撰写 release notes 文章;再把博客内容搬到 GitHub release notes,删除 Jekyll 特有的头部和<!-- more -->标记;

  • 更新 Slack 频道话题,引用下一个计划版本。

版本号一致性:如何验证发布没有漏改

整个流程中最关键的防错手段是发布前的git grep A.B.C。用当前仓库的实际分布做参照,一次合格的发布应当让下列位置全部从旧版本切换到新版本(当前值均为1.13.4):

$ git grep -n "1.13.4" -- README.md contrib/utils.sh contrib/coreos/user-data.example \ docs/_includes/_get-the-source.rst docs/troubleshooting_deis/index.rst deisctl/client/client.go README.md:9:[![Current Release](http://img.shields.io/badge/release-v1.13.4-1eb0fc.svg)]... contrib/coreos/user-data.example:114:... install.sh | sh -s 1.13.4' contrib/coreos/user-data.example:128: DEIS_RELEASE=v1.13.4 contrib/utils.sh:17:export DEIS_RELEASE=1.13.4 deisctl/client/client.go:276: [default: v1.13.4] docs/_includes/_get-the-source.rst:9: $ git checkout v1.13.4 docs/troubleshooting_deis/index.rst:110:``deisctl refresh-units --tag=v1.13.4``...

可以看到同一版本号的引用形式并不统一:README 徽章和 user-data 里带v前缀(v1.13.4),contrib/utils.sh的DEIS_RELEASE与 Dockerfile 的ENV DEIS_RELEASE不带v,client.go默认 tag 带v——这正是必须用-f显式指定旧字符串、并在全量 grep 中留意前缀差异的原因。此外 docs/reference/api-v1.7.rst 中示例响应的DEIS_PLATFORM_VERSION: 1.13.4、各安装文档中的下载链接版本号,也都属于这份清单的覆盖范围。

小结

Deis v1 的发布流程本质上是一套以 tag 为发布单元、以版本号字符串一致性为核心校验目标的手工 checklist:

  • 补丁版本 = 旧 tag 检出 + cherry-pick + 全量 bumpver + 手工 CHANGELOG + tag 推送,master 随后同步版本号;
  • 主次版本 = master 直发 +-dev后缀两阶段替换 +RefreshUnits默认 tag 切换 + 脚本生成 CHANGELOG + 博客与 release notes;
  • 任何版本都要触发四平台客户端安装器的 CI 构建、更新 deis.io 安装脚本与 ReadTheDocs 已发布版本;
  • 自动化由 bumpver(批量、可校验的 semver 替换)与 generate-changelog.sh(基于 conventional commit 的 changelog 聚合)承担,两者都有对应的测试与构建入口(contrib/bumpver/Makefile、contrib/bumpver/bump_test.go),其余环节则以“从上到下执行、跳过不适用项、流程变化时回写本文档”的方式由维护者手工完成。

这套流程的适用前提是 Deis v1 仓库自身的组织结构(多组件 Dockerfile、DEIS_RELEASE环境变量约定、deis.io 安装脚本),阅读清单时应以仓库当前实际文件为准——正如清单自己所要求的那样,文件列表会随代码库演进而需要更新。

  • 后端
  • 云原生

【免费下载链接】deis

Deis v1, the CoreOS and Docker PaaS: Your PaaS. Your Rules.

项目地址:https://gitcode.com/gh_mirrors/de/deis
点击查看免费下载
上一篇:VueUse useStepper 实战指南:用组合式 API 构建响应式多步骤向导表单
下一篇:PyPTO 逐元素比较运算 ge:Tensor 大于等于比较的实现原理与实战用法

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询