uv icon indicating copy to clipboard operation
uv copied to clipboard

Add a subcommand for reading/bumping the version in pyproject.toml

Open cauebs opened this issue 1 year ago • 21 comments

:white_check_mark: Both Rye and Poetry have this, and it's quite useful both...

  • to avoid manually incrementing the version number (and potentially making a mistake there with the digits),
  • and to have this field on the pyproject.toml file serve as the single source of truth for a project's version, easily accessible (via uv) in CI workflows, etc.

:stop_sign: The latter is where my personal interests lie: I have a CI workflow that tags and deploys releases when the version is bumped, currently using Poetry for it. I don't really want to pull in an additional tool to parse the project specs, so it's currently keeping me from considering migrating to uv.

:scroll: My proposal is replacing the current functionality of the version subcommand with this, since uv's version can already be accessed via the -V | --version option, and other project management currently exist as "root" subcommands.

:information_source: I'm willing to give this one a go myself if maintainers greenlight the proposal.

cauebs avatar Aug 21 '24 04:08 cauebs

Would maintaining version identifiers outside of pyproject.toml be considered out of scope for uv? For instance, updating something like a __version__ in a src/package/__init__.py?

Or, even better, support a dynamic version like hatch does with a

[project]
dynamic = ["version"]

[tool.hatch.version]
path = "src/package/__init__.py"

JonZeolla avatar Aug 22 '24 14:08 JonZeolla

It's most convenient to me to have git tag based versioning:

https://github.com/mtkennerly/poetry-dynamic-versioning

I would love to have this functionality.

deadnews avatar Aug 22 '24 15:08 deadnews

Would also love to see this... I'm currently using poetry-version-plugin in versioned projects and want to switch them to uv

raayu83 avatar Aug 29 '24 12:08 raayu83

Also very interested in this feature. This kind of read/update version command seems very common (not only Poetry but npm, etc) and it'd make migration to uv from other tools that much more straightforward.

Would maintaining version identifiers outside of pyproject.toml be considered out of scope for uv? For instance, updating something like a version in a src/package/init.py?

@JonZeolla I've used PDM's dynamic versioning in the past (which is essentially the same as the Hatch example you provide) but have found it kind of annoying in practice. IMO it's preferable to have the version in pyproject.toml be the source of truth. That version can be exposed in the Python package using importlib.metadata.version:

[tool.poetry]
name = "my-package"
version = "1,2,3"
# my_package/__init__.py

from importlib.metadata import version

__version__ = version("my_package")

menzenski avatar Sep 05 '24 11:09 menzenski

Personally I also like the idea of basing the version on the current git tag when using together with CI/CD. In that case it would be great if there was a command to set the version in pyproject.toml to the value of the git tag.

raayu83 avatar Sep 05 '24 13:09 raayu83

Personally I also like the idea of basing the version on the current git tag when using together with CI/CD.

In that case it would be great if there was a command to set the version in pyproject.toml to the value of the git tag.

Covering what bump-my-version (and previously bumpversion) do would cover that (including customizing the git tag and commit message format)

An interesting addition would be to have a way to trigger a custom script to bump the CHANGELOGs like a hook to a python script.

An even better but probably too opinionated option could be to add a CHANGELOG management system (like changie) but it might be out of scope of uv?

HenriBlacksmith avatar Sep 06 '24 20:09 HenriBlacksmith

For others who need this.

uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version $VERSION

I'm using it like this in github action.

VERSION=$(uvx dunamai from any --no-metadata --style pep440)
uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version $VERSION
uv build

phi-friday avatar Sep 07 '24 04:09 phi-friday

Consider how poetry does it: https://python-poetry.org/docs/cli#version

My workflow looks like this:

# Show current version
poetry version

# Bump version
poetry version minor

# Add a git tag with a matching version to what's in pyproject.toml
git tag "v$(poetry version -s)"

Poetry tries to be clever to avoid needing an option to specify whether you are auto-bumping or manually setting a version:

The new version should be a valid PEP 440 string or a valid bump rule: patch, minor, major, prepatch, preminor, premajor, prerelease

This assumes that no-one will ever want to use one of those strings as a version, but that seems like a reasonably safe assumption.

daviewales avatar Sep 11 '24 00:09 daviewales

With hatch even when you have the version set as dynamic and red from an example __about__.py module and you bump hatch version $(git describe --broken --tags --always --dirty) (that what I do on build in CI/CD) it will actually change the python module. Which is kinda nice.

pkucmus avatar Sep 12 '24 19:09 pkucmus

With hatch even when you have the version set as dynamic and red from an example __about__.py module and you bump hatch version $(git describe --broken --tags --always --dirty) (that what I do on build in CI/CD) it will actually change the python module. Which is kinda nice.

Using uvx hatch version ... is mostly fine, but I can't use it when it's a stub only package because there is no *.py.

phi-friday avatar Sep 14 '24 10:09 phi-friday

I'd love to see something like this as well - I currently use python-semantic-version but that uses SemVer rather than PEP440 - which causes a few minor issues such as not being able to parse tags that are valid PEP440 but not SemVer git tags (i.e. tags we added before migrating to PSV). It also has a nice CHANGELOG generation module, and the ability to generate release or dev version based on branch name (main vs feature). Version bumping rules are based on commit message parsing (i.e. if message starts with feat: bump minor version, if fix: bump patch etc.). As part of the PSV build process, all files that are modified (i.e. pyproject.toml, version.py) are staged, committed and pushed. The commit is also tagged with the version. You can then filter by the commit message in your CI pipeline to prevent infinite recursion.

david-waterworth avatar Oct 10 '24 02:10 david-waterworth

As a workaround, I use this in my project:

sed -i -e "s/0.0.0/${GITHUB_REF#refs/*/}/" pyproject.toml

https://github.com/astral-sh/packse/blob/70abfe8f64a9746452c02cb514942f879c7eaccc/.github/workflows/release.yaml#L34-L36

zanieb avatar Oct 14 '24 16:10 zanieb

As a workaround, I use this in my project:

sed -i -e "s/0.0.0/${GITHUB_REF#refs/*/}/" pyproject.toml

https://github.com/astral-sh/packse/blob/70abfe8f64a9746452c02cb514942f879c7eaccc/.github/workflows/release.yaml#L34-L36

Exactly what I did, I just wasn't comfortable w/ it

struckchure avatar Oct 14 '24 16:10 struckchure

Is there a reason why this won't/can't be implemented?

struckchure avatar Oct 14 '24 16:10 struckchure

The uv version command already exists, so I need to come up with a design to either phase that out in favor this functionality or choose a new command name.

Basically, that part isn't trivial and we're doing a lot of other things.

zanieb avatar Oct 14 '24 16:10 zanieb

@zanieb according to the docs there are already other ways to get the uv version.

E.g.

uv --version      # Same output as `uv version`
uv -V             # Will not include the build commit and date
uv pip --version  # Can be used with a subcommand

samcorky avatar Oct 14 '24 17:10 samcorky

@sam57719 that doesn't mean it's not a breaking change to switch the functionality. There is downstream code that will break if we change it.

zanieb avatar Oct 14 '24 17:10 zanieb

The uv version command already exists, so I need to come up with a design to either phase that out in favor this functionality or choose a new command name.

Basically, that part isn't trivial and we're doing a lot of other things.

Maybe we could just have a way to bump by updating the .toml file? something like ...

uv build --override-config "project.version=x.x.x"

Maybe someone already thought of that, I'm new to uv 🤷‍♂️

struckchure avatar Oct 14 '24 17:10 struckchure

Related: https://github.com/astral-sh/uv/issues/6440

chrisrodrigue avatar Oct 14 '24 17:10 chrisrodrigue

Here's a workaround that may help wait for the feature: uv tree --depth 0 shows the tree of version dependencies of ... just our package:

$ uv tree --depth 0
Resolved 66 packages in 1ms
mass-driver v0.18.0a1

Noting the "Resolved 66 packages in 1ms" is coming on stderr (debug message), so with a bit of fanciful shell:

$ uv tree --depth=0  2> /dev/null | awk '{print $2}'
v0.18.0a1

Not perfect, but it's a start!

PS: Still would love the feature, and personally believe the breakage/change of semantics of uv version is worth it (given uv -V and uv self both exist), but I understand this requires careful thought.

OverkillGuy avatar Oct 20 '24 06:10 OverkillGuy

That uv tree -q removes the actual tree output itself is probably a bug and now reported #8379

bluss avatar Oct 20 '24 08:10 bluss

Hi everyone, I'm new to this and have a question about the version bump functionality. Since the existing uv version command poses challenges for integrating version bumping, would it make sense to introduce a new subcommand like uv project? This subcommand could handle project-related tasks, including version management. For example: uv project --bump-patch uv project --bump-minor uv project --bump-major Would this approach help avoid conflicts with the existing uv version command and provide a dedicated space for expanding project management features in the future?

Satge96 avatar Oct 24 '24 06:10 Satge96

Thanks for engaging on the design!

I think that uv project might be weird since all the other "project" commands are top-level, e.g., init, sync, lock are all project operations.

zanieb avatar Oct 24 '24 12:10 zanieb

Thanks for engaging on the design!

I think that uv project might be weird since all the other "project" commands are top-level, e.g., init, sync, lock are all project operations.

I was wondering whether it’d be an opportunity to reconsider that since right now there isn’t a consistent mental model for what things update pyproject.toml, the lock file, or the venv. A dedicated project command would allow setting other things like bumping the target Python version as well.

acdha avatar Oct 24 '24 12:10 acdha

Maybe the top level command could be something like:

  • uv bump python <version> - increase the minimum required python version to the given version (if the given version is lower or equal to the current minimum an error is given), the allowed syntax for the given version should adhere to the Python requests format
  • uv bump python --minor - increase the minimum required python version to the next highest minor version
  • uv bump python --major - increase the minimum required python version to the next highest major version
  • uv bump project <version> - increase the project version to the given version (if the given version is lower or equal to the current version an error is given), the allowed syntax for the given version should follow semantic versioning with an optional v character at the start
  • uv bump project --patch - increase the project version to the next highest patch version
  • uv bump project --minor - increase the project version to the next highest minor version
  • uv bump project --major - increase the project version to the next highest major version

CarrotManMatt avatar Oct 24 '24 15:10 CarrotManMatt

Bumpver would be a good project for inspiration. I submitted https://github.com/mbarkhau/bumpver/issues/239, but it was closed as a duplicate of https://github.com/mbarkhau/bumpver/issues/193, which seems like it's a ways off.

epicserve avatar Oct 31 '24 13:10 epicserve

Bumpver would be a good project for inspiration. I submitted https://github.com/mbarkhau/bumpver/issues/239, but it was closed as a duplicate of https://github.com/mbarkhau/bumpver/issues/193, which seems like it's a ways off.

Looks a bit older compared to: https://github.com/callowayproject/bump-my-version but I assume uv maintainers already have good references 😃

HenriBlacksmith avatar Oct 31 '24 17:10 HenriBlacksmith

Retitled to try to improve discoverability. We get a lot of duplicates of this one.

zanieb avatar Nov 02 '24 13:11 zanieb

The uv version command already exists, so I need to come up with a design to either phase that out in favor this functionality or choose a new command name.

fwiw - when I first used uv at the very early stages, I instinctively thought the version subcommand would replicate the poetry version et al. behaviour. It would probably make more sense to keep uv related commands under uv self (ie. uv self version) and keep the top-level subcommands as project / environment scoped commands.

nc9 avatar Nov 08 '24 08:11 nc9

So, imagine we have dozens of poetry based projects that use Jenkinsfiles configured to use poetry version to build versioned prod docker images. And in order to get this version, we either go back to the good old setuptools days or use some python -c 'import toml ... hacks, which obviously nobody will do. This basically means uv cannot be used as a build tool for us 😿 which is a shame. A workaround with pyproject-info could work, but if you have dependency groups in your pyproject.toml, the toml is no longer PEP 621 compliant, and it fails. uv ability to resolve project versions is very important, in our case it is a blocker for its adoption, unfortunately.

tastyminerals avatar Nov 26 '24 13:11 tastyminerals