发布流程

本页说明 Maigret 的发布是如何进行的、仓库中每个 git 标签的含义,以及各项自动化分别由什么触发。内容面向维护者,以及需要确认从哪个 ref 构建的下游打包者。

版本号存放在哪里

版本号存放在两个文件中,必须同时修改:

  • pyproject.toml 中 [tool.poetry] 下的 version 字段

  • maigret/__version__.py 中的 __version__ 字符串

snap 打包通过 craftctl set version 读取的是 maigret/__version__.py,而进入 PyPI 元数据的是 pyproject.toml。两者不一致会导致软件包自报一个版本、却以另一个版本发布。

创建发布

  1. 从 main 拉出分支。分支通常以版本号命名,例如 0.6.5。

  2. 在该分支上修改上述两个版本文件。

  3. 为版本提升提交 pull request,使其与其他改动一样经过评审。

标签将建立在发布分支上。它与 main 分离是有意为之:标签必须指向版本文件已经写着新版本号的提交,而该提交要等发布完成之后才会进入 main。

发布

创建 GitHub Release,标签为 vX.Y.Z,目标为发布分支。发布这一动作正是触发其余所有流程的事件,因此发布说明应当在发布之前写好,而不是之后补写。

有两个工作流监听 release: types: [published]:

  • python-publish.yml 构建源码分发包和 wheel,并通过 trusted publishing 上传到 PyPI。

  • pyinstaller.yml 在 Wine 下构建 maigret_standalone.exe 并附加到该发布。由于 PyInstaller 在 Wine 下较慢,二进制文件会在发布本身出现几分钟之后才附上。

两者都检出 refs/tags/vX.Y.Z,因此构建的都是已发布的代码,而不是某个分支的当前头部。

备注

pypi 环境没有设置任何保护规则,因此发布任何 Release 都会不经人工审核直接把软件包送往 PyPI。若从某个版本号尚未出现在 PyPI 上的分支发布测试 Release,该版本会被真实发布出去。

发布之后

把发布分支合并进 main。实际操作中,这通常发生在 Release 发布后的几分钟内。

推送到 main 是另一个独立的触发器,它会启动常规自动化:每夜 Windows 构建、Docker Hub 镜像、站点数据库刷新以及测试套件。

由于发布分支是以 squash 方式合并的,落到 main 上的提交并不是标签所指向的那个提交。也就是说 vX.Y.Z 并不是 main 的祖先。这属于预期行为,也正因如此,打包者应当从标签构建,而不是到分支历史里去找它。

本仓库中的标签

发布标签,``vX.Y.Z``。不可变,每次发布一个,指向发布分支的顶端。这是打包者唯一应当据以构建的标签。

每夜标签,``nightly-main`` 和 nightly-dev。这是会移动的标签。对应分支的每次推送都会重新构建 Windows 二进制文件,并把标签强制更新到构建所用的提交,因此标签始终与附带的 .exe 相符。它们背后的 Release 被标记为预发布,所以永远不会从正式发布那里夺走 "latest" 标记。切勿把任何东西固定到这些标签上:ref 是稳定的,内容不是。

遗留标签,``main``、dev、test 以及 dev-564 到 dev-571。它们是早期 Windows 构建流程的残留,当时直接用分支名作为标签名。现在已经没有任何东西再创建或更新它们。其中两个仍然挂着附带 Windows 二进制文件的 GitHub Release,构建于 2026 年 4 月,因此从那里下载到的东西都是旧的。

警告

名为 main 的标签会遮蔽同名分支。git rev-parse main 会警告 refname 有歧义并返回标签,于是 git show main:some/file 读到的是标签所指提交的内容,而不是分支头部。凡是解析裸 ref 的工具都会踩到这一点:被要求构建 main 的远程构建可能构建的是标签。请显式使用 refs/heads/main,或者用 --no-tags 克隆。站点数据工作流的做法是在动任何 ref 之前先执行一步 git tag -d main。

产物最终去向

发布时自动产出:

  • PyPI,源码分发包和 wheel。

  • GitHub Release 附件,Windows 版 maigret_standalone.exe。

每次推送到 main 时自动产出:

  • Docker Hub,CLI 镜像和 web 镜像。

手动发布:

  • Snap,使用 snapcraft 构建,并上传到 amd64 与 arm64 的 latest/stable 通道。上传新版本不会改动商店页面:摘要、描述和图标只有在运行 snapcraft upload-metadata <snap-file> 时才会更新,因此每当 snap/snapcraft.yaml 中这些字段发生变化时都要运行它,否则商店会继续显示旧文本。

在本仓库之外由下游维护:

  • AUR、Homebrew core、MacPorts 和 nixpkgs 通常无需催促,会在一两天内跟进新版本。

  • BlackArch 通过向 BlackArch 仓库提交 pull request 来更新。