Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/cibuildwheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,16 @@ jobs:
name: Upload to PyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
if: |
always() &&
github.event_name == 'push' &&
startsWith(github.ref, 'refs/tags/') &&
needs.build_sdist.result == 'success' &&
(needs.build_wheels.result == 'success' || needs.build_wheels.result == 'failure')

Copilot AI Mar 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition needs.build_wheels.result == 'failure' is satisfied both when only one matrix leg fails (the intended partial-failure case) and when every single wheel build fails (all 9 matrix jobs fail). In the total-failure case, upload_pypi will still run and attempt to publish — but only the sdist artifact will exist, with no wheels at all.

While skip-existing: true prevents duplicate uploads, publishing a tag release to PyPI with zero wheels is likely unintentional and could result in an incomplete release reaching users.

Consider adding an explicit guard against a complete wheel build failure, for example by restricting the condition to needs.build_wheels.result == 'success' only, and relying on re-runs with skip-existing: true to handle truly flaky partial failures. Alternatively, if partial-failure publishing is genuinely desired, the PR description and/or a workflow comment should document this tradeoff explicitly.

Suggested change
(needs.build_wheels.result == 'success' || needs.build_wheels.result == 'failure')
needs.build_wheels.result == 'success'

Copilot uses AI. Check for mistakes.
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
id-token: write # mandatory for OIDC trusted publishing
attestations: write # needed by pypa/gh-action-pypi-publish >= v1.12 for Sigstore attestations
contents: read # needed to read repo contents for attestation metadata

steps:
- uses: actions/download-artifact@v4
Expand Down
Loading