setup-python 必须在 twine 之前运行,否则 pip install twine 可能因 python 环境缺失而失败;python -m build 会报 modulenotfounderror,因 github actions 默认不预装 build 工具链,需显式 pip install build 以确保兼容性。

setup-python 必须在 twine 之前运行,否则 pip install twine 可能因 Python 环境缺失而失败
为什么不能直接用 python -m build 就完事?
本地能跑通不代表 CI 能过。GitHub Actions 默认不带 build 工具链,python -m build 会报 ModuleNotFoundError: No module named 'build'。必须显式安装 build 或确保 Python 版本 ≥3.11 且已预装(但 GitHub 托管运行器不保证这点)。
- 推荐统一用
pip install build,兼容所有 Python ≥3.7 - 避免依赖系统预装,尤其 Windows 运行器上
build几乎总缺失 -
pyproject.toml中若声明了requires = ["setuptools>=45", "wheel", "build"],仅靠该声明不足以触发自动安装 —— GitHub Actions 不解析该字段来预装依赖
twine upload 报错 403 Client Error 怎么办?
这是最常卡住的环节,本质是凭据权限问题,不是网络或包格式错误。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 绝对不要把
API_TOKEN写死在 workflow 文件里,也别用secrets.PYPI_API_TOKEN—— PyPI 官方不认可该 secret 名,且语义不清 - 正确做法:在 PyPI 账户设置中创建一个 Scoped API token(限制为仅当前项目),然后存为仓库 secret:
PYPI_API_TOKEN(名称可自定义,但需与 workflow 中引用一致) - 上传命令必须加
--skip-existing,否则重复发布同版本会 409;同时建议加--verbose方便定位失败阶段 - 如果用
github_token传给 PyPI(不推荐),PyPI 会拒绝 —— 它只认__token__用户名 + token 密码,且不接受 GitHub 的 JWT
如何让 Semantic Release 自动推 Tag 并生成 Changelog?
Semantic Release 本身不生成 PyPI 包,它只管 Git 操作和版本号。要让它和构建发布联动,关键在触发时机和环境隔离。
- 必须将
semantic-release步骤放在构建前,且只在push到main时运行(不能用pull_request触发) - 用
actions/checkout@v4时务必加fetch-depth: 0,否则semantic-release算不出上次 tag -
pyproject.toml中的[tool.semantic_release]配置项不会被 GitHub Actions 自动读取,必须通过--config-file显式传入,或改用环境变量控制 - Changelog 写入
CHANGELOG.md是默认行为,但注意:该文件必须已存在(哪怕空),否则semantic-release会静默失败
为什么 trusted publisher 设置后还是提示未授权?
Trusted Publisher 是 GitHub Packages 的机制,对 PyPI 无效。很多人混淆了这两者。
- PyPI 不支持 GitHub 的 OIDC 流程,所以
trusted publisher对twine upload完全无用 - 真正要用 OIDC 发布到 PyPI,得走
pypa/gh-action-pypi-publish这类社区 Action,它内部封装了 token 交换逻辑 - 如果你坚持用原生
twine,就老老实实配secrets.PYPI_API_TOKEN;想省 token 管理,才值得引入 OIDC +pypa/gh-action-pypi-publish - 验证是否生效:成功发布后,PyPI 页面右下角会显示 “Uploaded via GitHub Actions” 字样,而不是 “Uploaded via twine”
__version__ 写死在 __init__.py,又用 semantic-release 自动生成 tag,结果两者不一致 —— 构建出的包版本和 Git tag 对不上,后续任何自动化都会失效。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










