执行摘要
本 PR 修复了 setuptools-scm 版本解析中因 strverscmp 排序导致的 rc 标签错误优先问题,通过提取 Python 脚本统一版本逻辑,确保 PyPI 发布构建正确版本,影响所有构建流程和依赖管理。
功能与动机
为什么做:在同时存在稳定标签(如 v0.5.10)和候选版本标签(如 v0.5.10rc0)时,git tag --sort=-version:refname 使用的 strverscmp 算法会错误地将 rc 标签排在稳定标签之上,导致 PyPI 发布工作流构建错误的 rc 版本(如失败运行所示)。这直接影响发布质量和用户体验。
实现拆解
按模块拆解改动:
- 工具模块:新增
python/tools/get_version_tag.py 脚本,实现核心版本解析:
parse_version_tuple:按 PEP 440 顺序解析版本标签为排序元组。
get_exact_version_tag:优先使用 git describe --exact-match 处理 CI 标签。
get_latest_version_tag_describe:为开发安装提供回退,通过排序和祖先检查找到最高版本标签。
- CI 模块:修改
.github/workflows/release-pypi-nightly.yml 和 .github/workflows/release-pypi-pr.yml,将原 bash 命令替换为 python3 ../python/tools/get_version_tag.py。
- 配置模块:更新所有 pyproject*.toml 文件(如
python/pyproject.toml),将 git_describe_command 从 git 命令改为调用新脚本。
评论区精华
提炼最有价值的讨论:
gemini-code-assist[bot] 指出:“The get_latest_version_tag_describe function is inefficient because it calls git describe in a loop for every version tag in the repository. Additionally, it still relies on git tag --sort=-version:refname, which incorrectly sorts rc tags above stable tags... This results in a version string like `0.5.10...”。
交锋与结论:评论强调了效率和正确性风险,但 PR 作者未直接回应,仅由 Fridge003 批准合并,表明问题可能被接受为已知限制或计划后续优化。
风险与影响
技术风险:
- 版本解析逻辑错误:
parse_version_tuple 函数依赖正则表达式处理标签格式,若遇到非标准标签可能导致解析失败。
- 构建效率问题:
get_latest_version_tag_describe 循环调用 git 命令,在大型仓库中可能拖慢构建性能。
- 依赖外部命令稳定性:脚本依赖 git 命令输出,跨平台或 git 版本变更可能引入兼容性问题。
影响评估:
- 用户影响:确保 PyPI 发布的包版本正确,避免安装错误 rc 版本。
- 系统影响:所有 setuptools-scm 构建流程(CI、本地)使用统一解析,提升版本一致性。
- 团队影响:需维护新脚本,但减少了因排序错误导致的发布故障。
关联脉络
与历史 PR 的关系:
- #22167 和 #22161:同属基础设施改进脉络,涉及 CI 工作流清理和脚本优化,显示团队对发布流程的持续维护。
- #22140:修复夜间测试,与 CI 可靠性相关,共同提升发布质量。
演进趋势:近期 PR 频繁涉及 run-ci、infra 和 consistency 标签,表明仓库正加强 CI/CD 自动化和配置统一性,本 PR 是这一趋势的具体体现。
参与讨论