Prhub

#22165 [Fix] Fix setuptools-scm version resolution for rc tags

原始 PR 作者 Kangyan-Zhou 合并时间 2026-04-06 07:55 文件变更 9 提交数 2 评论 1 代码增减 +179 / -16

执行摘要

修复 setuptools-scm 版本解析中 rc 标签排序错误,确保 PyPI 发布构建正确版本。

根据 PR body 描述,git tag --sort=-version:refname 使用 strverscmp 排序算法,导致 v0.5.10rc0 被排在 v0.5.10 之上,使得当两个标签同时存在时,PyPI 发布工作流会构建错误的版本(rc 版本而非稳定版本),如引用失败运行所示。

建议技术管理者审查 python/tools/get_version_tag.py 脚本的健壮性,特别是版本解析和祖先检查逻辑。工程师可参考此 PR 学习如何处理 git 标签排序和跨工作流版本控制,值得精读以理解基础设施改进策略。

讨论亮点

唯一 review 评论来自 gemini-code-assist[bot],指出 get_latest_version_tag_describe 函数效率低下(循环调用 git describe),且仍依赖有问题的 git tag --sort=-version:refname 排序,可能导致开发构建版本计算错误。评论建议优化祖先标签检索和使用合适版本解析器。Fridge003 批准了 PR,但未回应具体建议,表明问题被接受或推迟处理。

实现拆解

核心是新增 python/tools/get_version_tag.py 脚本,实现两步版本解析:先使用 git describe --exact-match 处理精确匹配的标签(用于 CI 标签构建);若无匹配,则通过解析 git 标签列表并按 PEP 440 顺序排序,结合祖先检查找到最高版本标签并生成描述字符串(用于开发安装)。修改了以下文件:

  1. .github/workflows/release-pypi-nightly.yml.github/workflows/release-pypi-pr.yml 替换原 bash 命令为调用新脚本。
  2. 所有 pyproject*.toml 文件(如 python/pyproject.toml)更新 git_describe_command 配置指向新脚本。
文件 模块 状态 重要度
python/tools/get_version_tag.py tools added 8.0
.github/workflows/release-pypi-nightly.yml CI modified 6.0
python/pyproject.toml configuration modified 7.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

parse_version_tuple run_git get_exact_version_tag get_latest_version_tag_describe

评论区精华

get_latest_version_tag_describe 函数的效率与正确性问题 正确性

gemini-code-assist[bot] 指出该函数效率低下且仍依赖有问题的 git tag 排序,可能导致开发构建版本错误。

结论:评论未被直接回应,但 PR 被批准,表明问题可能被接受或推迟处理。 · 待处理

风险与影响

技术风险包括:新脚本的版本解析逻辑(如 parse_version_tuple 函数中的正则表达式)可能未覆盖所有边缘情况(如非标准标签格式),引发版本错误;依赖 git 命令的稳定性和跨平台兼容性;函数效率问题可能影响大型仓库的构建性能;如果脚本失败,setuptools-scm 可能回退到错误版本。具体风险点在于祖先检查逻辑和排序算法的正确性。

影响范围:确保 PyPI 发布的包版本正确,避免用户安装错误 rc 版本;所有基于 setuptools-scm 的构建流程(包括 CI、本地安装)将使用统一解析逻辑,提升一致性;团队需要维护新脚本,并确保其与未来 git 版本兼容。影响程度中等,主要作用于发布流程和依赖管理。

版本解析逻辑错误 构建效率问题 依赖外部命令稳定性

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

执行摘要

本 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 批准合并,表明问题可能被接受为已知限制或计划后续优化。

风险与影响

技术风险

  1. 版本解析逻辑错误parse_version_tuple 函数依赖正则表达式处理标签格式,若遇到非标准标签可能导致解析失败。
  2. 构建效率问题get_latest_version_tag_describe 循环调用 git 命令,在大型仓库中可能拖慢构建性能。
  3. 依赖外部命令稳定性:脚本依赖 git 命令输出,跨平台或 git 版本变更可能引入兼容性问题。

影响评估

  • 用户影响:确保 PyPI 发布的包版本正确,避免安装错误 rc 版本。
  • 系统影响:所有 setuptools-scm 构建流程(CI、本地)使用统一解析,提升版本一致性。
  • 团队影响:需维护新脚本,但减少了因排序错误导致的发布故障。

关联脉络

与历史 PR 的关系

  • #22167 和 #22161:同属基础设施改进脉络,涉及 CI 工作流清理和脚本优化,显示团队对发布流程的持续维护。
  • #22140:修复夜间测试,与 CI 可靠性相关,共同提升发布质量。

演进趋势:近期 PR 频繁涉及 run-ciinfraconsistency 标签,表明仓库正加强 CI/CD 自动化和配置统一性,本 PR 是这一趋势的具体体现。

参与讨论