简体   繁体   English

GitHub 操作 - 发布到 TestPyPI 和 PyPI 失败

[英]GitHub action - publishing to both TestPyPI and PyPI fails

I set up a GitHub workflow for publishing my Python project to (Test)PyPI according to this guide: https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ resulting in this workflow: https://github.com/felixocker/ontor/blob/main/.github/workflows/publish-to-pypi.yml我根据本指南设置了一个 GitHub 工作流,用于将我的 Python 项目发布到(测试)PyPI: https ://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions -ci-cd-workflows/导致此工作流程: https ://github.com/felixocker/ontor/blob/main/.github/workflows/publish-to-pypi.yml

Whenever I push to the main branch, a new TestPyPI release is created:每当我推送到主分支时,都会创建一个新的 TestPyPI 版本:

- name: Publish distribution to Test PyPI
  uses: pypa/gh-action-pypi-publish@master
  with:
    password: ${{ secrets.TEST_PYPI_API_TOKEN }}
    repository_url: https://test.pypi.org/legacy/

This works just fine, cp., eg, commit 15a3bf6这工作得很好,cp。例如,提交 15a3bf6

When I push with a tag, this should push to TestPyPI as usual, but the tag should also trigger pushing to PyPI:当我使用标签推送时,这应该像往常一样推送到 TestPyPI,但标签也应该触发推送到 PyPI:

- name: Publish distribution to PyPI
  if: startsWith(github.ref, 'refs/tags')
  uses: pypa/gh-action-pypi-publish@master
  with:
    password: ${{ secrets.PYPI_API_TOKEN }}

However, this fails with a 400 error, cp., eg, commit b450e0f:但是,这会失败并出现 400 错误,cp.,例如,提交 b450e0f:

ERROR    HTTPError: 400 Bad Request from https://test.pypi.org/legacy/
         File already exists. See https://test.pypi.org/help/#file-name-reuse
         for more information.

Interestingly, the error already occurs in the step for pushing to TestPyPI, and pushing to PyPI is skipped after that.有趣的是,在推送到 TestPyPI 的步骤中已经发生错误,之后跳过推送到 PyPI。 Also, when I tried uploading the latest version to PyPI manually, I got the same error.此外,当我尝试手动将最新版本上传到 PyPI 时,我得到了同样的错误。 After that manual attempt, the version was available via PyPI, though.不过,在那次手动尝试之后,该版本可以通过 PyPI 获得。

Really not sure what I am missing here - so pointers are greatly appreciated :)真的不确定我在这里缺少什么 - 所以非常感谢指针:)

################################################# ################################################

Edit #1:编辑#1:

The behavior makes sense to me for the commits 15a3bf6 and b5cade1, as I did not change the version number here.对于提交 15a3bf6 和 b5cade1,这种行为对我来说是有意义的,因为我没有在此处更改版本号。

What I just realized thanks to @Indra's response and the action overview is that the workflow is executed twice for the same commit: b450e0f in runs #33 and #34由于@Indra 的响应和操作概述,我刚刚意识到,工作流针对同一个提交执行了两次:b450e0f 在运行 #33 和 #34
Are there two runs because tags are treated as pushes of their own (which might be indicated by "v0.4.2" vs "main")?是否有两次运行,因为标签被视为自己的推送(可能由“v0.4.2”与“main”表示)?
I pushed the commit and the respective tag using我使用推送提交和相应的标签

git push --atomic origin main <tag>

which should be simultaneous, though.不过,这应该是同时的。
If so, is there a way to keep the intended behavior: "publish to TestPyPI whenever I push to main, publish to PyPI whenever there is a tag" without having two runs, assuming that I update the version?如果是这样,有没有办法保持预期的行为:“只要我推送到 main,就发布到 TestPyPI,只要有标签就发布到 PyPI”,假设我更新了版本,不需要两次运行?

In your error message it should be clear that your workflow attempt to upload the same package version to TestPyPI.在您的错误消息中,应该清楚您的工作流程尝试将相同的包版本上传到 TestPyPI。 PyPI doesn't allow to upload package with the same version more than once. PyPI 不允许多次上传相同版本的包。 See here .这里 That's why you get File already exists error.这就是为什么你得到File already exists错误。

In your TestPI workflow:在您的 TestPI 工作流程中:

- name: Publish distribution to Test PyPI
  uses: pypa/gh-action-pypi-publish@master
  with:
    password: ${{ secrets.TEST_PYPI_API_TOKEN }}
    repository_url: https://test.pypi.org/legacy/

GitHub actions will upload the package to TestPyPI whenever you push to the repository.每当您推送到存储库时,GitHub 操作都会将包上传到 TestPyPI。 If your package point to the same version when you push more than once, the workflow will fail because the package already uploaded to TestPyPI on the first push.如果您的包在多次推送时指向同一个版本,则工作流将失败,因为包已在第一次推送时上传到 TestPyPI。

Everything works fine.一切正常。 Version 0.3.7 was uploaded to TestPyPI on GitHub push to main branch.版本 0.3.7 已上传到 GitHub 上的 TestPyPI 推送到主分支。

Package version still point to 0.3.7.包版本仍然指向 0.3.7。 GitHub push to main branch trigger actions and try to reupload the package to TestPyPI and failed because the version already exists. GitHub 推送到主分支触发操作并尝试将包重新上传到 TestPyPI 并失败,因为版本已经存在。

GitHub action skip upload to PyPI because the commit is not tagged. GitHub 操作跳过上传到 PyPI,因为未标记提交。

Package version changed to 0.4.0.包版本更改为 0.4.0。 The first push successfully build and upload the package to TestPyPI, but subsequent upload failed.第一次推送成功构建并上传包到TestPyPI,但后续上传失败。 The error still the same, GitHub actions try to upload the package with the same version.错误还是一样,GitHub actions 尝试上传相同版本的包。

So on.很快。

You could change the TestPyPI workflow to upload only on tagged commit or you could change the package version whenever you push to the GitHub repository.您可以将 TestPyPI 工作流程更改为仅在标记提交时上传,或者您可以在推送到 GitHub 存储库时更改包版本。 The first solution would be more feasible.第一个解决方案会更可行。

TestPyPI:测试PyPI:

- name: Publish distribution to Test PyPI
  if: startsWith(github.ref, 'refs/tags')
  uses: pypa/gh-action-pypi-publish@master
  with:
    password: ${{ secrets.TEST_PYPI_API_TOKEN }}
    repository_url: https://test.pypi.org/legacy/

PyPI:派皮:

- name: Publish distribution to PyPI
  if: startsWith(github.ref, 'refs/tags')
  uses: pypa/gh-action-pypi-publish@master
  with:
    password: ${{ secrets.PYPI_API_TOKEN }}

So here is what happened:所以这就是发生的事情:
Apparently, GitHub treats the pushes for a commit and a tag separately even when using显然,即使在使用时,GitHub 也会分别处理提交和标签的推送

git push --atomic origin main <tag>

via SSH, see this discussion .通过 SSH,请参阅此讨论
This results in the github action being run twice, as it is triggered by every push.这会导致 github 操作运行两次,因为它是由每次推送触发的。 The version number is already being used for TestPyPI in the first run, yielding a file already exists error in the second.版本号已在第一次运行时用于 TestPyPI,在第二次运行时产生文件已存在错误。

What worked for me:什么对我有用:
Making the two cases for pushing to TestPyPI and PyPI exclusive according to this discussion as such:根据此讨论,将推送到 TestPyPI 和 PyPI 的两种情况设为独占:

    - name: Publish distribution to Test PyPI
      if: ${{ !startsWith(github.ref, 'refs/tags') }}
      uses: pypa/gh-action-pypi-publish@master
      with:
        password: ${{ secrets.TEST_PYPI_API_TOKEN }}
        repository_url: https://test.pypi.org/legacy/
    - name: Publish distribution to PyPI
      if: startsWith(github.ref, 'refs/tags')
      uses: pypa/gh-action-pypi-publish@master
      with:
        password: ${{ secrets.PYPI_API_TOKEN }}

Whenever a commit without a tag is pushed to GitHub, this triggers the push to TestPyPI.每当将不带标签的提交推送到 GitHub 时,都会触发推送到 TestPyPI。 When a tag is pushed, the version is released to PyPI.推送标签时,版本会发布到 PyPI。 A caveat is that the commit must be handled by the action before the tag, which, in my case, did not work for commit f732bda.需要注意的是,提交必须由标记之前的操作处理,在我的情况下,这对提交 f732bda 不起作用。 Also, as mentioned by @Indra, the version number must be incremented for the action to work.此外,正如@Indra 所述,必须增加版本号才能使操作生效。 Alternatively, a distinction between regular and hierarchical tags, eg, "v0.3.0/beta", could be made as described here .或者,可以如这里描述的那样区分常规标签和分层标签,例如“v0.3.0/beta”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM