GitHub Action发布Python包到TestPyPI和PyPI失败排查
问题根因
你遇到的400报错核心原因是触发了重复的工作流运行:
- 使用
git push --atomic origin main <tag>推送时,GitHub会将main分支推送、标签推送识别为两个独立的push事件,启动两次完全独立的工作流,两次运行检出的是同一个commit,构建出的分发包版本、文件名完全一致 - 现有工作流没有给TestPyPI发布步骤加执行范围限制,两次工作流启动后都会优先执行TestPyPI上传操作。第一次运行成功上传包到TestPyPI后,第二次运行再上传完全相同的文件,就会触发平台的文件重名拦截,返回400错误
- 工作流默认单步失败即中止后续流程,因此如果标签对应的工作流是后启动的,TestPyPI步骤报错后,后续的正式版PyPI发布步骤会直接被跳过
你之前手动上传PyPI时遇到相同报错但最终包上线,也是同样逻辑:第一次触发的流程已经完成了上传,你重复上传时被平台拦截,但文件实际已经存在于服务端。
解决方案
直接给TestPyPI发布步骤增加执行条件判断,仅在普通main分支推送(非标签触发)的场景下运行TestPyPI发布即可,修改后的TestPyPI步骤代码如下:
- name: Publish distribution to Test PyPI if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.TEST_PYPI_API_TOKEN }} repository_url: https://test.pypi.org/legacy/
调整后的运行逻辑完全符合你的预期:
- 普通提交推送到main分支:满足判断条件,正常发布版本到TestPyPI
- 带标签推送时:标签触发的工作流会直接跳过TestPyPI发布步骤,不会出现重复上传同版本包的问题,后续判断为标签事件的PyPI正式版发布步骤会正常执行
额外注意事项
- 请将pypi发布Action的引用从
@master改为固定的版本tag(比如示例中的@release/v1),避免master分支出现不兼容变更导致流程故障 - 每次打正式版标签前必须更新项目版本号,PyPI和TestPyPI均不允许覆盖已上传的同版本文件,版本号不变的情况下任何上传操作都会报400错误
内容的提问来源于stack exchange,提问作者lixi
相关产品推荐
相关产品推荐

