Headlamp 发布指南:从版本号提升到多渠道分发的完整 Release 流程
Headlamp 发布指南:从版本号提升到多渠道分发的完整 Release 流程
导读
本文基于 Headlamp 官方发布指南(docs/development/release-guide.md)并结合仓库内的自动化发布工具(tools/releaser)源码,系统梳理 Headlamp 一次完整版本发布的全流程:从创建发布分支、提升版本号、生成发布草稿与编写发布说明,到构建各平台安装包、推送资产、打标签、触发容器镜像构建,直至 flathub、homebrew 等分发渠道的联动更新。读完本文,你将掌握 Headlamp 的发布节奏与每一步的操作要点,并能熟练使用 releaser 命令行工具与 push-release-assets.js 脚本完成自动化发布。
Headlamp 的发布理念是:把步骤以指南形式列出,并逐步用自动化工具替代手工操作,让未来每次发布所需的人工步骤尽可能少。目前版本号提升、打标签、发布校验等环节已由 tools/releaser 工具链自动化,而创建发布草稿、触发平台构建等仍依赖 GitHub Actions 工作流。
一、发布前的准备:版本策略与前置条件
Headlamp 遵循 语义化版本(Semantic Versioning) 规范,版本号格式为 X.Y.Z,其中:
X为主版本号(major):不兼容的 API 变更时递增;Y为次版本号(minor):向后兼容的功能新增时递增;Z为修订号(patch):向后兼容的缺陷修复时递增。
从 tools/releaser/src/utils/version.ts 的实现看,工具对版本号做了严格校验:isValidVersion() 要求版本必须符合严格 SemVer 格式,不允许前导空格、不允许前导 v 或 =、不允许包含 + 构建元数据,但允许预发布版本(如 0.24.0-rc1)。sanitizeVersion() 则会自动去除用户误输入的前导 v 并给出警告。因此,执行发布时传入 0.42.0 这样的版本号即可,无需手动加 v 前缀(前缀只在打 Git 标签时才会出现)。
判定"可以发布"的标准是:自上次发布以来积累了值得发布的变更,且 QA 已完成。随后进入正式发布流程。
二、Step 1:创建发布分支
在准备发布时,先基于 main 创建一个新的发布分支。原文档建议分支名为 rc-X.Y.Z(X.Y.Z 为新版本号);而当前仓库中 releaser start 命令实际创建的分支名为 hl-rc-<version>(见 tools/releaser/src/commands/start.ts 中 const branchName = \hl-rc-${version}`` 一行)。手工操作等价于:
git checkout -b rc-X.Y.Z
如果分支已存在,releaser start 会检测到并停留在当前分支,避免误建重复分支(branchExists() 通过 git rev-parse --verify 判断)。
三、Step 2:版本号提升(bump version)
版本号提升是发布的核心步骤,涉及多个文件必须同步更新。推荐使用仓库内的自动化工具 Headlamp Releaser 完成。
方式一:使用 releaser 工具(推荐)
进入 tools/releaser 目录安装依赖、编译并链接为全局命令,然后执行 start:
# 进入 releaser 目录,安装依赖,编译并链接
cd tools/releaser
npm install
npm run build && npm link
# 启动发布,X.Y.Z 为目标版本号
releaser start X.Y.Z
根据 tools/releaser/README.md 与 start.ts 源码,releaser start <release-version> 会依次自动完成:
- 校验版本号:不符合严格 SemVer 则直接报错退出;
- 创建并切换到发布分支
hl-rc-<version>(除非指定--no-branch); - 更新 app/package.json 的
version字段 为新版本号; - 更新 charts/headlamp/Chart.yaml 的
version与appVersion两个字段 为新版本号(脚本会先用正则确认这两个键存在,缺失则抛错); - 在
app/目录下执行npm install,同步刷新package-lock.json; - 执行
make helm-update-template-version重新生成 Helm 模板的期望快照(见 Makefile 中同名目标),该步骤需要机器上装有make、bash和helm,否则会报错提示; - 自动提交变更,提交信息为
releaser: bump version to X.Y.Z。
其中第 7 步的提交行为在 tools/releaser/src/utils/git.ts 的 commitVersionChange() 中有明确实现:git add 依次加入 app/package.json、app/package-lock.json、charts/headlamp/Chart.yaml 以及 charts/headlamp/tests/expected_templates 整个目录,然后以 git commit --signoff -m "releaser: bump version to X.Y.Z" 提交(带 sign-off)。
启动成功后,工具会提示下一步可以执行 releaser tag 与 releaser publish X.Y.Z。
方式二:手工提升版本号
若在特殊情况下需要手工操作,则在发布分支上:
- 修改 app/package.json 中的
version字段; - 在
app/目录运行npm install更新package-lock.json; - 如适用,同步更新 Helm Chart 版本与模板(charts/headlamp/Chart.yaml);
- 暂存并提交:
git add app/package.json app/package-lock.json charts/headlamp/Chart.yaml charts/headlamp/tests/expected_templates
git commit --signoff -m "releaser: bump version to X.Y.Z"
关于 Bug Fix 分支
如果是修复既有版本的 bug 而发补丁版:可以从上一个 tag 拉出分支,把相关提交 cherry-pick 进去;也可以从 main 拉分支并去掉与上一个 tag 之间的 merge commit(去掉 merge commit 时在该分支上执行 git rebase main)。核对自某版本以来的提交可以用:
git log v0.25.0.. --oneline
四、Step 3:创建发布草稿(Release Draft)
版本号提升并提交后,需要创建一个 GitHub Release 草稿。这一步通过手动运行仓库的 "Create release draft" GitHub Actions 工作流完成(workflow_dispatch 手动触发)。注意:必须填写正确的发布名称,因为工作流会用该名称生成草稿中的链接,名称通常与版本号一致(如 0.5.3)。
上图即该工作流的运行界面:左侧是包含 "Create Release Draft" 在内的发布流水线步骤,右侧弹出 "Run workflow" 触发框,可选择目标分支(main)并输入发布名称。该工作流属于整个发布流程的关键节点,其后依次衔接 "Build App"、"Build Container and test" 等环节。
五、Step 4:核对自上次发布以来的变更并编写发布说明
发布草稿创建后,需要核对自上次发布以来的全部变更,用于填写发布说明。查看变更列表:
git log `git describe --abbrev=0`..
即从最近一个可注解的 tag 到当前 HEAD 之间的全部提交。随后打开上一步创建的发布草稿,将变更分类整理进去。编写发布说明的要点(参考历史发布的惯例):
- 面向读者写作:去掉类似
frontend:的组件前缀上下文,直接说明变更内容; - 致谢外部贡献者:在行末以
(thanks @XXX )的格式列出外部贡献者的用户名。
六、Step 5:应用签名
应用签名由构建脚本自动处理,发布者无需手工干预。相关实现见 app/scripts/after-pack.js、app/mac/scripts/codeSign.js 以及 app/windows/codesign.js、app/windows/sign.js 等脚本,它们分别在打包后处理、macOS 签名与 Windows 签名环节工作。
七、Step 6:为各平台生成安装包
针对 Linux、Windows、macOS 三个平台,在 rc-X.Y.Z 分支上手动触发 "Build and upload PLATFORM artifact" 系列 GitHub Actions 工作流,分别生成对应平台的安装包产物。
该环节也可以用 releaser 工具自动化触发与查询:
# 为指定 git ref(分支或 tag)触发所有平台的构建
releaser ci app --build v0.42.0
# 只触发 Linux 平台的构建并跳过确认提示
releaser ci app --build main --platform linux --force
# 列出最近一次各平台的构建运行情况
releaser ci app --list
# 以 JSON 格式列出最近 3 次 Mac 平台的构建运行
releaser ci app --list --platform mac --latest 3 --output json
从 tools/releaser/src/index.ts 的命令定义看,ci app 子命令支持 --build <git-ref>、--list、-p/--platform(可选 all、windows、mac、linux,默认 all)、--latest <number>(默认 1)、-o/--output(simple 或 json)与 --force 等选项;--build 与 --list 不能同时使用,且二者必选其一,否则报错退出。
八、Step 7:下载并测试构建产物
下载各平台生成的安装包产物,在对应平台上进行安装与功能测试。测试通过后,将这些产物上传到新发布的资产(assets)区域。
发布前的完整性校验可以使用 releaser 的 check 命令:
# 校验某版本是否存在,且 Mac/Linux/Windows 三平台产物是否齐全
releaser check 0.42.0
根据 tools/releaser/src/commands/check.ts 的实现,check 会:确认 release 存在(不存在则报错退出);显示其状态(草稿或已发布、tag 名称、发布时间);逐一核对 Mac、Linux、Windows 三平台所需产物,缺失则报错退出。对已发布的 release,还会进一步检查扩展资产:核心资产包括容器镜像(containerImage)、Homebrew、winget、Chocolatey、Flatpak、Docker 扩展,附加资产包括 Helm 与 Minikube;工具会分别汇总核心与附加资产的可用状态并给出提示。
九、Step 8:推送资产到 Release
上传二进制产物到 release 的资产区,使用仓库自带的脚本 app/scripts/push-release-assets/push-release-assets.js。该脚本(基于 Octokit 与 mime-types 实现)会:
- 将指定资产推送到 release;
- 自动识别并设置正确的资产类型(MIME type);
- 计算各文件的 SHA 校验和,更新并上传
checksums.txt校验和文件。
基本用法(需先设置 GITHUB_TOKEN 环境变量):
GITHUB_TOKEN=MY_TOKEN_123 node ./app/scripts/push-release-assets.js v0.19.0 Headlamp....tar.gz
脚本还支持以下选项(见脚本开头 yargs 参数定义):
| 选项 | 说明 |
|---|---|
--force / -f |
即使 release 已不再是草稿状态也继续推送 |
--skip-checksums |
跳过 checksums.txt 的更新 |
--only-checksums |
只根据给定文件生成并推送 checksums.txt,不上传文件本身 |
脚本的其余行为细节:如果 release 上已存在同名资产会先删除再重新上传;checksums.txt 若已存在,会先下载现有内容、合并新文件校验和后重新生成(按文件名排序)。关于 Token 的获取:如果本机安装了 gh 命令行工具,可直接使用 gh auth token 获取当前登录凭据;也可以按 GitHub 官方指引创建个人访问令牌(personal access token)。
十、Step 9:合并回 main 并推送新标签
测试与资产上传完成后,将发布分支合并回 main,并打上带 v 前缀的注解标签:
git tag vX.Y.Z -a -m "Release X.Y.Z"
注意:以下命令只在新功能版本(feature release)发布时执行,不要在任何其他情况下运行:
git checkout main
git merge rc-X.Y.X # 由于发布分支只有 bump 提交这一处差异,不应产生 merge commit
git push origin main
git push --tags
标签创建也可以通过 releaser 自动完成。releaser tag 命令会读取 app/package.json 中的当前版本号,自动创建格式为 v<version>、消息为 Release <version> 的注解标签(对应 git.ts 中 createReleaseTag():git tag -a v${version} -m "Release ${version}"),并且不需要在命令行再传版本号:
releaser tag
发布(Publish):关联草稿并正式发布
草稿、标签与资产都就绪后,最后一步是正式发布。releaser publish <release-version> 会依次:
- 推送 tag 到远端(
git push origin v<version>); - 找到对应的 release 草稿;
- 将 tag 与草稿关联;
- 将草稿标记为已发布。
# 交互式确认后发布(默认会弹出确认提示)
releaser publish 0.42.0
# 跳过确认提示直接发布(不可逆操作,请谨慎)
releaser publish 0.42.0 --force
从 tools/releaser/src/commands/publish.ts 源码看,--force 用于跳过 inquirer 交互式确认;发布是不可逆操作,工具会明确提示 "This action cannot be undone"。
十一、Step 10:容器镜像与分发渠道
- 容器镜像:每次创建 tag 时,CI 会自动构建容器镜像并推送到 GitHub Container Registry(ghcr.io),无需人工干预;
- 其他分发渠道:flathub、homebrew、minikube 等渠道会通过自动打开的 PR 完成版本更新。
releaser check在发布后重跑一次,即可校验这些扩展资产(容器镜像、Homebrew、winget、Chocolatey、Flatpak、Docker 扩展、Helm、Minikube)是否都已就绪(见上文 Step 7 的说明)。
十二、Step 11:社交媒体公告
发布完成后,联系社交团队(如 Joaquim 或 Chris)从官方社交媒体账号发布公告(toot / tweet / post)。
十三、发布前的安全检查(可选但推荐)
在发布前,建议额外运行 releaser 的 security-check 命令,对后端与 Dockerfile 做一次安全扫描:
releaser security-check
该命令(见 tools/releaser/src/commands/security-check.ts)会使用 govulncheck 扫描 Go 后端模块(backend)的已知漏洞,并用 hadolint 检查 Dockerfile、Dockerfile.plugins 与 docker-extension/Dockerfile 的 Dockerfile 安全问题(如未固定软件包版本、管道式 RUN 命令缺少 pipefail 等)。任一检查发现问题即以非零码退出;若对应工具不在 PATH 中,则该检查项会以警告形式跳过(govulncheck 需要 Go 工具链,hadolint 通过 Docker 容器运行以避免本地安装)。
十四、Releaser 工具全景速查
tools/releaser 是一个专为 Headlamp 发布流程设计的 CLI 工具(Node.js >= 20.11.1、npm >= 10.0.0,需要 Git 推送权限,以及带 repo、workflow、read:packages 权限的 GITHUB_TOKEN)。其命令定义集中在 tools/releaser/src/index.ts,汇总如下:
| 命令 | 作用 | 示例 |
|---|---|---|
releaser start <version> |
建发布分支、提升版本号、装依赖、重生成 Helm 模板并提交 | releaser start 0.42.0 |
releaser start <version> --no-branch |
在当前分支上完成版本号提升,不建新分支 | releaser start 0.42.0 --no-branch |
releaser tag |
根据 app/package.json 版本创建 v<version> 注解标签 |
releaser tag |
releaser check <version> |
校验 release 与各平台产物/扩展资产是否齐全 | releaser check 0.42.0 |
releaser publish <version> |
推 tag、关联草稿并正式发布(--force 跳过确认) |
releaser publish 0.42.0 |
releaser ci app --build <ref> |
触发指定 ref 的多平台构建 | releaser ci app --build v0.42.0 |
releaser ci app --list |
列出最近的构建运行情况 | releaser ci app --list --platform mac --latest 3 --output json |
releaser security-check |
扫描后端漏洞与 Dockerfile 安全问题 | releaser security-check |
一次完整的典型发布工作流(来自 tools/releaser/README.md)可以归纳为:
export GITHUB_TOKEN=your-token-here
# 1. 开始发布:建分支、提升版本号、装依赖、重生成模板并提交
releaser start 0.42.0
# 2. 通过 GitHub Actions 的 "Create Release Draft" 工作流创建发布草稿
# 在 UI 中传入 releaseName: 0.42.0
# 3. 创建注解标签 v0.42.0
releaser tag
# 4. 校验草稿及其必需产物(Mac/Linux/Windows)
releaser check 0.42.0
# 5. 推 tag、关联草稿并正式发布(不可逆)
releaser publish 0.42.0
# 6.(可选)发布后重跑 check,校验容器镜像、Homebrew、winget、
# Chocolatey、Flatpak 等扩展资产是否就绪
releaser check 0.42.0
结语
Headlamp 的发布流程已高度工程化:版本号提升、Helm 模板同步、标签创建、产物校验与正式发布均由 releaser 工具自动化,发布草稿与多平台构建则由 GitHub Actions 工作流承接,容器镜像与各分发渠道的更新在打标签后自动触发。整个流程中发布者真正需要手工关注的,主要是:确认发布内容与 QA 状态、创建发布草稿时填对版本号、编写面向用户的发布说明,以及下载各平台产物做最终验收。本文涉及的脚本与工具源码均可直接在仓库内查阅:tools/releaser、app/scripts/push-release-assets、app/electron-builder.config.ts 与 app/scripts。
