Skip to content

fix(packaging): bundle LICENSE in wheel and sdist#1354

Merged
mergify[bot] merged 1 commit intomainfrom
devs/jd/worktree-rust-port/bundle-license-wheel-sdist--e4571775
May 5, 2026
Merged

fix(packaging): bundle LICENSE in wheel and sdist#1354
mergify[bot] merged 1 commit intomainfrom
devs/jd/worktree-rust-port/bundle-license-wheel-sdist--e4571775

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented May 5, 2026

The 2026.5.5.1 release upload to PyPI failed with
400 License-File LICENSE does not exist in distribution file mergify_cli-2026.5.5.1.tar.gz at mergify_cli-2026.5.5.1/LICENSE.

Maturin auto-derives a License-File: LICENSE PEP 639 metadata
field from license = "Apache-2.0" plus the project root
LICENSE file, but the sdist tarball (maturin sdist) packs
the cargo workspace and the Python source dir without picking up
the project root LICENSE itself. PyPI's upload validator
cross-checks the metadata against the tarball contents and 400s
when they disagree.

Listing LICENSE in [tool.maturin].include puts it back in
both the wheel and the sdist, so the metadata claim is honored and
PyPI accepts the upload.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

The 2026.5.5.1 release upload to PyPI failed with
``400 License-File LICENSE does not exist in distribution file
mergify_cli-2026.5.5.1.tar.gz at mergify_cli-2026.5.5.1/LICENSE``.

Maturin auto-derives a ``License-File: LICENSE`` PEP 639 metadata
field from ``license = "Apache-2.0"`` plus the project root
``LICENSE`` file, but the sdist tarball (``maturin sdist``) packs
the cargo workspace and the Python source dir without picking up
the project root ``LICENSE`` itself. PyPI's upload validator
cross-checks the metadata against the tarball contents and 400s
when they disagree.

Listing ``LICENSE`` in ``[tool.maturin].include`` puts it back in
both the wheel and the sdist, so the metadata claim is honored and
PyPI accepts the upload.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Change-Id: Ie45717750af52467929600966592cb8453d3b4d2
Copilot AI review requested due to automatic review settings May 5, 2026 10:12
@mergify mergify Bot deployed to Mergify Merge Protections May 5, 2026 10:12 Active
@jd
Copy link
Copy Markdown
Member Author

jd commented May 5, 2026

This pull request is part of a Mergify stack:

# Pull Request Link
1 fix(packaging): bundle LICENSE in wheel and sdist #1354 👈
2 ci(packaging): validate sdist+wheel metadata with twine on every PR #1355
3 chore(port): drop PORT_STATUS.toml inventory in favor of port-and-delete #1351
4 feat(rust): port queue pause and unpause to native Rust (Phase 1.5) #1352
5 feat(rust): port ci git-refs and ci queue-info to native Rust (Phase 1.6) #1353

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 5, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 🤖 Continuous Integration

Wonderful, this rule succeeded.
  • all of:
    • check-success=ci-gate

🟢 👀 Review Requirements

Wonderful, this rule succeeded.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?:

🟢 🔎 Reviews

Wonderful, this rule succeeded.
  • #changes-requested-reviews-by = 0
  • #review-requested = 0
  • #review-threads-unresolved = 0

🟢 📕 PR description

Wonderful, this rule succeeded.
  • body ~= (?ms:.{48,})

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Python packaging configuration so the generated distributions include the repository LICENSE, matching the PEP 639 metadata that maturin derives and preventing PyPI release uploads from being rejected.

Changes:

  • Add LICENSE to [tool.maturin].include in pyproject.toml.
  • Document why the license file must be bundled in both wheel and sdist artifacts.
  • Align package contents with the License-File: LICENSE metadata expected by PyPI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pyproject.toml
@jd jd marked this pull request as ready for review May 5, 2026 10:14
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 5, 2026

Merge Queue Status

  • Entered queue2026-05-05 10:24 UTC · Rule: default
  • Checks skipped · PR is already up-to-date
  • Merged2026-05-05 10:25 UTC · at 9c79dec9b4ecfb76810263d36f419e9384dce1fa · squash

This pull request spent 15 seconds in the queue, including 3 seconds running CI.

Required conditions to merge

@mergify mergify Bot merged commit 83d34c0 into main May 5, 2026
22 checks passed
@mergify mergify Bot deleted the devs/jd/worktree-rust-port/bundle-license-wheel-sdist--e4571775 branch May 5, 2026 10:25
@mergify mergify Bot added queued and removed queued labels May 5, 2026
mergify Bot pushed a commit that referenced this pull request May 5, 2026
…1355)

Without this, packaging-metadata bugs only surface at
``release: published`` time — release 2026.5.5.1 was rejected by
PyPI's upload validator with ``400 License-File LICENSE does not
exist in distribution file`` because the LICENSE auto-bundling
hadn't been wired up. PR CI couldn't have caught it: ``build-sdist``
was gated on ``inputs.stamp-version``, so PR runs skipped the sdist
entirely, and there was no twine invocation anywhere.

Two changes:

1. ``build-sdist`` now runs on every PR. The version-stamping step
   and the artifact upload still gate on ``inputs.stamp-version``
   (PR builds keep the placeholder version and skip the upload —
   the artifact is only useful for the publish job in
   ``release.yml``). The Python toolchain is provisioned the same
   way as the wheel jobs.

2. ``twine check --strict`` runs against both the wheel (per
   matrix target) and the sdist immediately after each is built.
   Strict mode applies the same metadata rules PyPI's upload
   validator does — README rendering,
   ``Description-Content-Type``, ``License-File`` presence — so a
   mismatch fails PR CI instead of the next release.

The cost is one extra ubuntu-24.04 job (~30s for sdist + twine
check) and a few seconds per wheel-matrix shard for the twine
install + check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Depends-On: #1354
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants