通过GitHub Actions推送至PyPI:如何处理无版本号更新的变更?
解决GitHub Actions触发PyPI重复发布失败的方案
方案1:仅在版本号或源码变更时触发发布
核心思路是让GitHub Actions只在仓库的源码文件或版本配置文件(比如pyproject.toml、setup.py这类记录版本号的文件)发生变更时,才执行发布流程,跳过仅修改CI配置(如.github/workflows/下的文件)的提交。
实现方式
- 通过工作流的路径过滤设置触发条件:
也可以用排除法跳过CI配置变更:on: push: branches: [master] paths: - '**.py' # 匹配所有Python源码文件 - 'pyproject.toml' # 匹配Poetry版本配置文件 - 'setup.py' # 匹配setuptools版本配置文件 # 可根据项目结构补充其他源码/版本相关路径on: push: branches: [master] paths-ignore: - '.github/workflows/**' # 忽略所有CI工作流文件的修改 - 增加前置版本校验:在发布步骤前,用脚本对比当前版本与PyPI已发布版本,仅当版本不一致时才执行发布:
CURRENT_VERSION=$(poetry version --short) PYPI_VERSION=$(pip show your-package-name | grep Version | awk '{print $2}') if [ "$CURRENT_VERSION" != "$PYPI_VERSION" ]; then poetry publish --build else echo "当前版本与PyPI已发布版本一致,跳过发布" fi
方案2:忽略PyPI重复发布的400错误
如果需要保留全量触发逻辑,可让发布步骤在遇到重复发布的400错误时不终止整个工作流,仅标记该步骤为成功或跳过。
实现方式
- 在发布步骤中启用错误续跑:
- name: Publish to PyPI uses: JRubics/poetry-publish@v1.16 with: poetry_version: '1.6.1' pypi_token: ${{ secrets.PYPI_TOKEN }} continue-on-error: true - 或者通过shell命令捕获特定错误,仅在非重复发布错误时终止流程:
- name: Publish to PyPI run: | set +e poetry publish --build EXIT_CODE=$? # 仅当错误码不是重复发布相关时才终止 if [ $EXIT_CODE -ne 0 ] && ! echo "$(poetry publish --build 2>&1)" | grep -q "File already exists"; then exit $EXIT_CODE fi exit 0 env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
方案对比
- 方案1更严谨,能避免不必要的PyPI请求,减少无效操作,是优先推荐的方案。
- 方案2适合需保留全量触发的场景,但无法区分真实发布错误(如权限问题、包格式错误)与重复发布,可能掩盖潜在问题。
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

