Skip to content

Build releases with the pinned hatchling and a publish action that accepts Metadata 2.5 - #3380

Merged
maxisbey merged 1 commit into
mainfrom
fix-publish-metadata-2.5
Aug 24, 2026
Merged

Build releases with the pinned hatchling and a publish action that accepts Metadata 2.5#3380
maxisbey merged 1 commit into
mainfrom
fix-publish-metadata-2.5

Conversation

@maxisbey

Copy link
Copy Markdown
Contributor

The v2.1.0 Publishing run built fine but the upload step rejected the distributions before anything reached PyPI:

Checking dist/mcp-2.1.0-py3-none-any.whl: ERROR InvalidDistribution: Invalid distribution metadata: '2.5' is not a valid metadata version

Motivation and Context

Two things combined:

  • The build job runs uv 0.9.5, which does not apply [tool.uv].build-constraint-dependencies to uv build. The hatchling==1.29.0 pin in pyproject.toml therefore never applied to release builds (the 2.0.0 wheel on PyPI says Generator: hatchling 1.31.0), and since hatchling 1.32.0 (2026-08-11) the floating build writes Metadata-Version: 2.5.
  • The publish step is pinned to gh-action-pypi-publish v1.14.0, whose bundled metadata check predates 2.5. The v1.x workflow floats on release/v1 (currently v1.14.2) and published a Metadata 2.5 wheel for v1.29.1 without complaint a few minutes earlier.

This bumps uv to 0.12.5 in the build job only, so the existing constraint takes effect (verified locally: uv 0.9.5 builds with hatchling 1.32.0 / Metadata 2.5; uv 0.11.15 and 0.12.5 build with hatchling 1.29.0 / Metadata 2.4, version-from-tag and the mcp-types== pin unchanged), and moves the publish action pin to v1.14.2 so a future metadata bump is not fatal either. The uv pin used by CI (shared.yml, conformance.yml) is left alone here.

How Has This Been Tested?

Rebuilt both packages from this branch with uv 0.9.5, 0.11.15 and 0.12.5 and compared METADATA/WHEEL; twine check --strict passes on all of them. The workflow itself only runs on release: published, so the real test is re-cutting v2.1.0 from the merge commit.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

AI Disclaimer

…on that accepts current metadata

The release build ran uv 0.9.5, which does not apply
[tool.uv].build-constraint-dependencies to `uv build`, so the hatchling
pin in pyproject.toml never took effect there and the build floated to
hatchling 1.32.0, which writes Metadata-Version 2.5. The publish step was
pinned to gh-action-pypi-publish v1.14.0, whose metadata check predates
2.5 and rejected the distributions before upload.

Use uv 0.12.5 for the build job so the constraint applies (hatchling
1.29.0, Metadata-Version 2.4, matching what 2.0.0 shipped), and move the
publish action to v1.14.2, which also accepts 2.5.

No-Verification-Needed: workflow-only change; reproduced both builds locally

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/publish-pypi.yml">

<violation number="1" location=".github/workflows/publish-pypi.yml:24">
P2: The release builds remain unpinned because `uv build` is not given a build-constraints file. Pass the repository's build constraints explicitly (or otherwise make the build step consume them); changing the uv version alone does not apply `[tool.uv].build-constraint-dependencies` here.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread .github/workflows/publish-pypi.yml
@maxisbey
maxisbey merged commit 4d6f87e into main Aug 24, 2026
36 checks passed
@maxisbey
maxisbey deleted the fix-publish-metadata-2.5 branch August 24, 2026 18:57

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Beyond the inline nit, I checked the uv-bump rationale — pyproject.toml (lines 42-45) does pin hatchling==1.29.0 via [tool.uv].build-constraint-dependencies, so building with a uv version that honors it is consistent — but I could not verify from this environment that the new pypa/gh-action-pypi-publish commit (publish-pypi.yml line 60) actually is tag v1.14.2; since that step runs with id-token: write for trusted publishing, please confirm the SHA-to-tag mapping upstream before merging.

Extended reasoning...

The diff is two pin changes in the release workflow: uv 0.9.5 → 0.12.5 in the build job, and the publish action moved from a release/v1 commit to a commit annotated v1.14.2. The uv side checks out locally — the hatchling==1.29.0 build constraint the PR says will now take effect is present in pyproject.toml, and the setup-uv action SHA itself is unchanged and matches the one used across shared.yml, conformance.yml, and the docs workflows. What I could not do is verify the new gh-action-pypi-publish SHA against the upstream v1.14.2 tag (no network access here); because this workflow holds the OIDC trusted-publishing credential, an incorrect or malicious SHA is the one meaningful supply-chain risk in the change, and it takes a human ten seconds to confirm on GitHub. That open check, not any defect found in the diff, is why I'm deferring rather than approving.

Comment on lines 21 to +24
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: false
version: 0.9.5
version: 0.12.5

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟣 nit (pre-existing): the release build's setup-uv step lacks the manifest-fetch retry that shared.yml applies to the identical pinned setup-uv@ v8.2.0 invocation (comment there cites astral-sh/setup-uv#869: single request, hard 5s timeout), so the flake the repo already works around elsewhere can still fail the highest-stakes run of this step

Extended reasoning...

During a release (release: published), setup-uv's version-manifest fetch times out once (the known astral-sh/setup-uv#869 flake that shared.yml lines 20-35 explicitly retries around). In publish-pypi.yml there is no continue-on-error/retry pair, so the 'Install uv' step fails, the release-build job fails, and the maintainer must manually re-run the Publishing workflow before any distribution is built or uploaded. The bump to 0.12.5 keeps this step on the same un-retried single fetch, so the inconsistency with shared.yml's documented workaround persists in the one workflow where a transient failure blocks shipping a release.

Verification: pre-existing — The candidate is factually accurate. In .github/workflows/publish-pypi.yml lines 20-24, the release build's setup-uv step is a single bare invocation: uses: astral-sh/setup-uv@ fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with version: 0.12.5 and no continue-on-error/retry pair. By contrast, .github/workflows/shared.yml lines 20-35 wrap the identical pinned action in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant