astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
27.95k stars 803 forks source link

FR: `uv build` accepts a dynamic "package version" argument #8714

Open charlesnicholson opened 4 weeks ago

charlesnicholson commented 4 weeks ago

When we build "official" Python distribution package wheels from CI, we version the packages dynamically based on the current git tag. This is surprisingly complicated to do!

The build package doesn't support a dynamic version supplied from the command-line: https://build.pypa.io/en/stable/#python--m-build-options

So, we ended up using this thing: https://github.com/pypa/setuptools-scm?tab=readme-ov-file#pyprojecttoml-usage

Our pyproject.toml files look like this:

[project]
name = "my_company.package"
dynamic = ["version"]
...

And then we have to provide the version as an environment variable to the build:

SETUPTOOLS_SCM_PRETEND_VERSION=1.2.3 path/to/venv/bin/python -m build ...

It's all very roundabout and contrived; I just want to do this:

path/to/venv/bin/python -m build --version=1.2.3 ...

I don't know if there's appetite in extending uv build to solve this with fewer packages and with a simple command-line, but it would make our lives a lot simpler, and we'd be able to ditch both the build and the setuptools-scm packages in favor of stock uv.

zanieb commented 4 weeks ago

Seems sensible, although we probably need our own build backend to support this? I presume setting the dynamic version is build backend dependent and we're unlikely to tie into their options.

You could also change the version statically, per the workflow in https://github.com/astral-sh/uv/issues/6298, though that's annoying because if you want the committed pyproject.toml to be correct you need to do it ahead of time.

As a simple workaround, I set the version to 0.0.0 then do sed -i -e "s/0.0.0/${GITHUB_REF#refs/*/}/" pyproject.toml.

charlesnicholson commented 4 weeks ago

Thanks for the response! Yeah, I landed on the same options you did, I think- in the end I chose not to do in-place modifications of the git pyproject.toml files b/c we can sometimes do a "versioned" build locally and we have to remember to git-reset all of the toml files. So for us it's "better" to do this Rube Goldberg silliness :)

charlesnicholson commented 4 weeks ago

Also, re-reading your response saying "we're unlikely to tie into their options"- Sorry if I wasn't clear; I would love to fully abandon this setuptools-scm thing; it's just totally a hack I'm using because it just happens to have an environment-variable interface to setting the version in the distribution package!

zanieb commented 4 weeks ago

There's https://github.com/astral-sh/uv/issues/3957 to track implementation of our own build backend.

paveldikov commented 3 weeks ago

+1 on a UX/ecosystem level. Versioning is such a fundamental build concern and it is so unfortunate that developers have to dance around it with build-backend plugins -- it's super clunky and fragile. I can similarly attest to having burnt a lot of time shimming things with setuptools-scm and the like. Frankly, package versioning should have been externalised to begin with.

Architecturally though I'm a -0.5 as this somewhat violates PEP 517. In the current standard, dynamic versioning is fully controlled by the build-backend (as regrettable as this is). And so the only way for the frontend can influence the choice of version, is if the backend is actively willing to be influenced.

I.e. uv build --version 1.2.3 would only reliably result in a 1.2.3 version if and only if the build-backend is uv itself, or is similarly aware of some uv-specific build config API. A non-uv-aware backend would silently ignore this option, or even error out because it can't plug the metadata gap. This may be an acceptable compromise in the interim, FWIW.

(IMHO this problem should ultimately be solved at the PEP level)

charlesnicholson commented 3 weeks ago

Agreed, after reading up more on this, a uv build backend seems like the only sane place for such an implementation to live.

wu-clan commented 3 weeks ago

pdm does a great job at this:https://pdm-project.org/en/latest/reference/pep621/

zanieb commented 3 weeks ago

@wu-clan I don't see how that's any different than uv? That just looks like a PEP 621 reference guide.

wu-clan commented 3 weeks ago

@zanieb Yes, if you look closely, you'll find https://backend.pdm-project.org/metadata/#dynamic-project-version, which is a very useful feature, especially for libraries