TRL 版本发布流程全解:从 VERSION 版本约定到 PyPI 自动发布的完整操作手册
【免费下载链接】trlTrain transformer language models with reinforcement learning.项目地址: https://gitcode.com/GitHub_Trending/tr/trl
本文基于 TRL(Transformers Reinforcement Learning)仓库根目录的 RELEASE.md 整理,系统梳理该项目的版本号规范、Major/Minor 发布与 Patch 发布的完整 Git + CI 操作流程。读完本文,你将掌握:如何从
main分支拉出发布分支、在哪些文件中同步版本号、如何借助 GitHub Actions 自动把新版本发布到 PyPI、如何打 git tag 并维护v*-release补丁分支,以及如何在发布结束后把主干切回开发版本(dev version)。文中所有命令、diff 与分支命名均可在当前仓库中直接对照验证。
版本号约定:VERSION文件与v{major}.{minor}.{patch}规范
TRL 的版本号由仓库根目录下的 VERSION 文件唯一维护(当前文件内容为1.14.0.dev0,即处于 1.14 的预发布开发阶段)。RELEASE.md 开篇给出了一条强制约定:
VERSION 需要遵循
v{major}.{minor}.{patch}格式约定。必须遵循该约定,才能检索到带版本号的脚本(versioned scripts)。
这条约定在实际仓库中有两层体现:
- 版本字符串形态:
{major}.{minor}.{patch}三段式数字,开发阶段追加.dev0后缀,例如1.14.0.dev0; - git tag 形态:tag 名带
v前缀,例如v1.14.0(见下文发布流程中的git tag -a v{major}.{minor}.0)。
VERSION 文件如何进入构建链路
VERSION文件并不只是给发布者看的记号,它是打包系统与运行时的真实数据源:
- 在 pyproject.toml 中声明了动态版本:
version = { file = "VERSION" },即python -m build打包时直接从VERSION文件读取版本号写入 wheel/sdist 的元数据; - 在 trl/init.py 中,运行时通过
importlib.metadata.version("trl")读取已安装发行版的版本号,未安装(如直接跑源码目录)时回退为"unknown"; - 在 trl/scripts/env.py 中,
trl env命令会输出TRL version,并在存在 git commit 时拼接短哈希(如1.14.0.dev0+abc1234),方便排查问题。
因此,发布时修改VERSION文件等于同时决定了:打包产物的版本、运行时__version__、CI 发布判断的依据,三者必须保持一致。
分支模型总览:三类分支各司其职
从 RELEASE.md 的流程可以归纳出 TRL 使用的三类长期分支:
| 分支 | 命名示例 | 作用 |
|---|---|---|
main | main | 主开发线,日常 PR 合并目标,同时也是正式版本发布的目标分支 |
| 发布分支(临时) | release-v1.14 | 每次 Major/Minor 发布时从main拉出,版本号变更集中提交于此,经 PR 审查后合回main |
| 补丁分支(长期) | v1.14-release | 发布完成后建立,承载该 Minor 系列后续的 Patch 发布(1.14.1、1.14.2…),通过 cherry-pick 吸收主线的修复 |
这套模型保证了:main始终只含经过测试的代码(发布期间禁止合入其他 PR);Patch 发布与主开发线互不阻塞;已发布的 Minor 系列可以被持续维护。
Major/Minor 发布:完整十步流程
Major/Minor 发布(即1.13→1.14这类跨次版本号的发布)共十步,下面按 RELEASE.md 的顺序逐步展开,并补充每一步的仓库佐证与要点。
第 1 步:确保本地仓库与上游同步
git checkout main git pull origin main发布冻结警告:RELEASE.md 特别强调,在发布完成之前,不要把其他 pull request 合并进main,以保证发布版本稳定、不含未测试的变更。同时应在内部频道(文档中为 #trl-internal)向其他维护者通告正在发布,请大家暂停合并 PR,直到发布结束。这是整个流程中最容易出问题的一环:发布分支基于main创建,一旦创建后main又合入了新代码,发布版本就可能带上未经冻结验证的变更。
第 2 步:从 main 创建发布分支
git checkout -b release-v{major}.{minor}以发布 1.14 为例,即release-v1.14。所有版本号变更都集中在该分支上完成,避免直接改动main造成历史混乱。
第 3 步:在三个文件中更新版本号
这是版本信息同步的关键步骤,共涉及三个文件:
① .github/workflows/tests_latest.yml
- with: { ref: v{major}.{minor-1}-release } + with: { ref: v{major}.{minor}-release }该工作流名为 "Tests latest TRL release with dev dependencies",每日定时运行(cron 午夜 UTC),作用是用最新发布版+开发版依赖(accelerate / datasets / transformers 的 git 主分支)跑全量测试。当前仓库第 31 行仍是with: { ref: v1.13-release },即它检出的基线是上一个 Minor 系列的补丁分支——这正是 RELEASE.md 注释中"版本化脚本检索"的实际含义:CI 通过分支名/tag 反查历史发布版本。因此发布 1.14 时必须把它同步改为v1.14-release,否则 CI 会永远测试旧版本。
② CITATION.cff
- version: '{major}.{minor-1}' + version: '{major}.{minor}'CITATION.cff是引用元数据(当前为version: '1.13'),供学术引用与 GitHub 展示使用,发布时需与发行版本对齐。
③ VERSION
- {major}.{minor}.0.dev0 + {major}.{minor}.0把开发版本号1.14.0.dev0改为正式版本号1.14.0。如前所述,这一步直接决定打包产物版本。
第 4 步:提交并推送
git add .github/workflows/tests_latest.yml CITATION.cff VERSION git commit -m 'Release: {major}.{minor}' git push origin release-v{major}.{minor}提交信息示例为Release: 1.14。
第 5 步:创建 Pull Request
从release-v{major}.{minor}向main发起 PR,命名Release: v{major}.{minor}(如Release: v1.14),等待 CI 全部通过,并请求代码审查。
第 6 步:合并 PR,触发自动发布
PR 被批准并合并进main后,会自动把新版本发布到 PyPI。自动化的依据在 .github/workflows/publish.yml 中:
- 触发条件(第 3-9 行):
push到main或v*-release分支,且变更路径限定为VERSION; - 发布动作(第 37-43 行):用
python -m build构建包,再通过twine upload上传,密钥来自仓库 secrets(PYPI_TOKEN); - 关键防线(第 38 行):
if: ${{ !contains(steps.get_version.version, 'dev') }}—— 只有当VERSION内容不含dev时才真正上传 PyPI。这意味着开发版本号(如1.14.0.dev0)被推到main时不会误发布。
第 7 步:打 git tag 标记发布
git checkout main git pull origin main git tag -a v{major}.{minor}.0 -m 'Adds tag v{major}.{minor}.0 for PyPI' git push origin v{major}.{minor}.0使用带注释的 tag(-a)记录发布信息,tag 名为v1.14.0。
第 8 步:创建v{major}.{minor}-release补丁分支
git checkout -b v{major}.{minor}-release git push origin v{major}.{minor}-release该分支长期保留,目的是让后续补丁版本(1.14.1、1.14.2…)可以独立于main进行发布。同时它也是第 3 步中tests_latest.yml引用的 ref 来源。
第 9 步:创建 GitHub Release
- 进入仓库的 Releases 页面(原文档在 RELEASE.md 中通过链接指向该页面);
- 点击Draft a new release(草稿新发布);
- 选择第 7 步刚创建的
v{major}.{minor}.0tag; - 填写标题(如
v1.14.0)与简短的新特性说明; - 点击Publish Release发布。
第 10 步:把主干 bump 到开发版本
发布完成并不代表结束,main需要进入下一个开发周期:
从
main拉出分支bump-dev-version-{major}.{minor+1}:git checkout main git pull origin main git checkout -b bump-dev-version-{major}.{minor+1}修改 VERSION:
- {major}.{minor}.0 + {major}.{minor+1}.0.dev0即
1.14.0→1.15.0.dev0(当前仓库的1.14.0.dev0正是上一轮 bump 的产物)。提交并推送:
git add VERSION git commit -m '⬆️ Bump dev version' git push origin bump-dev-version-{major}.{minor+1}从
bump-dev-version-{major}.{minor+1}向main发起 PR,命名为⬆️ Bump dev version,请求紧急审查;批准后合入
main;代码库即进入下一个开发周期,并在内部频道告知团队。
Patch 发布:七步补丁流程
Patch 发布(如1.14.0→1.14.1)不需要触碰main,全程在补丁分支v{major}.{minor}-release上完成,共七步。
第 1 步:同步补丁分支
git fetch origin git checkout v{major}.{minor}-release git pull origin v{major}.{minor}-release第 2 步:cherry-pick 需要纳入补丁的提交
git cherry-pick <commit-hash-0> git cherry-pick <commit-hash-1> ...把主线中已合入的修复按需挑入补丁分支,保证补丁只包含经过确认的变更,不夹带未完成开发内容。
第 3 步:更新 VERSION
- {major}.{minor}.{patch-1} + {major}.{minor}.{patch}即1.14.0→1.14.1。
第 4 步:提交并推送
git add VERSION git commit -m 'Release: {major}.{minor}.{patch}' git push origin v{major}.{minor}-release第 5 步:等待 CI 通过并自动发布
推送后无需手动干预,CI 会自动把新补丁版本发布到 PyPI——由 publish.yml 的v*-release分支触发规则(第 5 行)保证,VERSION不含dev时即执行上传(第 38 行)。
第 6 步:打 git tag
git tag -a v{major}.{minor}.{patch} -m 'Adds tag v{major}.{minor}.{patch} for PyPI' git push origin v{major}.{minor}.{patch}例如v1.14.1。
第 7 步:创建 GitHub Release
流程与 Major/Minor 发布的第 9 步一致:进入仓库 Releases 页面 →Draft a new release→ 选择上一步的 tag → 填写标题(v{major}.{minor}.{patch})与变更说明 →Publish Release。
流程要点与常见误区
发布冻结期是硬性要求
从第 1 步到第 6 步(PR 合入main)之间,任何其他 PR 的合入都可能污染发布内容,破坏"发布版本仅含测试通过代码"的前提,务必全程遵守。
dev关键字是自动发布的安全阀
publish.yml 通过判断VERSION是否包含dev来决定是否上传 PyPI。这意味着开发版本(.dev0)即使被推送到main或v*-release分支也只会构建、不会上传,正式版本号(无dev)推送才会真正发布。手动操作时切勿把dev误留在正式发布版本的VERSION中。
tests_latest.yml的 ref 指向是发布质量闭环
tests_latest.yml 以最新发布版为基线、叠加三方库的开发分支(accelerate/datasets/transformers 的 git 主分支)来跑make test,相当于给"最新稳定版 + 未来依赖"的组合做持续回归。发布时若忘记同步其中的 ref,CI 将持续测试旧版本,新版回归风险无法被及时暴露。
三个文件必须同步修改
Major/Minor 发布第 3 步涉及tests_latest.yml、CITATION.cff、VERSION三个文件,它们分别服务于 CI 基线、引用元数据、打包版本,任何一处遗漏都会造成版本信息不一致(例如包内版本是 1.14 但引用元数据仍是 1.13)。
快速核对清单
发布前/后可按以下清单自检:
main已git pull最新,且发布期间无其他 PR 合入;- 发布分支名符合
release-v{major}.{minor}规范; tests_latest.yml的 ref 已指向v{新版本}-release;CITATION.cff的 version 已更新为{major}.{minor};VERSION已从{major}.{minor}.0.dev0改为{major}.{minor}.0(Patch 发布则为{patch-1}→{patch});- PR 命名规范(
Release: v{major}.{minor}),CI 通过且完成审查后合入; - tag 已打(
v{major}.{minor}.0或v{major}.{minor}.{patch})并推送; - GitHub Release 已创建;
- Minor 发布后已建立
v{major}.{minor}-release补丁分支; - Minor 发布后已把
VERSIONbump 到{minor+1}.0.dev0并合入main。
通过以上流程,一个 Minor 系列从开发、发布到持续维护的生命周期即可闭环;而对VERSION文件的每一次修改,都会经由 pyproject.toml 的version = { file = "VERSION" }与 publish.yml 的自动化判断,最终落实为 PyPI 上可安装、可复现的正式发行版。
【免费下载链接】trlTrain transformer language models with reinforcement learning.项目地址: https://gitcode.com/GitHub_Trending/tr/trl
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考