7

How would I use bump2version (with regards to its invocation and/or its configuration) to increment:

1.0.0.a2.post0 # post-release of a pre-release a2

to

1.0.0.a3 # pre-release a3

Reproducible example:

$ python3 -m pip install 'bump2version==1.0.*'

__init__.py:

__version__ = "1.0.0.a2.post0"

setup.cfg:

[bumpversion]
current_version = 1.0.0.a2.post0
parse = ^
    (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)  # minimum major.minor.patch, 1.2.3
    (?:
    \.
    (?P<prerel>a|alpha|b|beta|d|dev|rc)  # pre-release segment
    (?P<prerelversion>\d+)  # pre-release version num
    )?
    (?:\.post(?P<post>\d+))?  # post-release
serialize =
    {major}.{minor}.{patch}.{prerel}{prerelversion}.post{post}
    {major}.{minor}.{patch}.{prerel}{prerelversion}
    {major}.{minor}.{patch}.post{post}
    {major}.{minor}.{patch}

[bumpversion:file:__init__.py]

[bumpversion:part:prerel]
optional_value = dev
values =
    dev
    d
    alpha
    a
    beta
    b
    rc

Examples of valid versions from this scheme, which takes some but not all rules from PEP 440:

1.2.3             # (1) final

1.2.3.dev0        # (2) prerelease
1.2.3.a0
1.2.3.alpha0
1.2.3.b0
1.2.3.beta0
1.2.3.rc0

1.2.3.rc3.post0   # (3) postrelease (of a pre-release version)

1.2.3.post0       # (4) postrelease (of a final version)

I've tried, for example, bump2version --verbose prerelversion or alternatively with --new-version=1.0.0.a3 explicitly. Both of those attempts retain the .post0 rather than dropping it.


Note: I asked this as a usage question issue in the bump2version repo a few weeks back with no luck.

florisla
  • 12,668
  • 6
  • 40
  • 47
Brad Solomon
  • 38,521
  • 31
  • 149
  • 235

1 Answers1

4

We had to wrestle with that (and, back in the days, with the original bumpversion, not the nicer bump2version).

With the config below, you can use bumpversion pre to go from 1.0.0.a2.post0 to 1.0.0.a3.

Explanation:

Since pre and post each have both a string prefix and a number, I believe it is necessary to split them accordingly. For example, the pre part could be split into a prekind (the string) and a pre (the number). Then, the nice thing is that you can increment prekind ('dev' to 'alpha' to 'beta' etc.) independently of the issue number (a sequence, as usual).

Below, I've put both a complete configuration and an example with a number of invocations in sequence to show the various mutations that are possible. I'm sure the setup below can be further customized, but hopefully it will put you and others landing here on the right track.

cat > .bumpversion.cfg << "EOF"
[bumpversion]
current_version = 1.0.0.a2.post0
files = __init__.py
commit = False
parse = ^
        (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
        (\.(?P<prekind>a|alpha|b|beta|d|dev|rc)
        (?P<pre>\d+)  # pre-release version num
        )?
        (\.(?P<postkind>post)(?P<post>\d+))?  # post-release
serialize = 
        {major}.{minor}.{patch}.{prekind}{pre}.{postkind}{post}
        {major}.{minor}.{patch}.{prekind}{pre}
        {major}.{minor}.{patch}.{postkind}{post}
        {major}.{minor}.{patch}

[bumpversion:part:prekind]
optional_value = _
values =
    _
    dev
    d
    alpha
    a
    beta
    b
    rc

[bumpversion:part:postkind]
optional_value = _
values =
    _
    post
EOF

echo '__version__ = "1.0.0.a2.post0"' > __init__.py

Tests:

These perform a sequence of bumpversion operations to demonstrate some of the mutations that are possible. And of course, you can use --new-version=... to forcefully set a new version.

for op in \
    start post post pre pre prekind prekind pre postkind post prekind minor \
    postkind post pre postkind prekind postkind post major prekind postkind post; do
  if [[ $op == 'start' ]]; then
    printf "starting from: %s\n" $(perl -ne 'print "$1\n" if /"(.*)"/' __init__.py)
  else
    bumpversion $op
    printf "%10s --> %s\n" $op $(perl -ne 'print "$1\n" if /"(.*)"/' __init__.py)
  fi
done

Output (commented):

starting from: 1.0.0.a2.post0
      post --> 1.0.0.a2.post1   # no issue incrementing post
      post --> 1.0.0.a2.post2   
       pre --> 1.0.0.a3         # can move to the next 'pre'release
       pre --> 1.0.0.a4 
   prekind --> 1.0.0.beta0      # can upgrade the kind of prerelease
   prekind --> 1.0.0.b0 
       pre --> 1.0.0.b1         # and keep incrementing 
  postkind --> 1.0.0.b1.post0   # bring a post component again  
      post --> 1.0.0.b1.post1   # and incrementing
   prekind --> 1.0.0.rc0        # upgrade pre kind directly
     minor --> 1.1.0            # patch/minor/major cut the optional parts
  postkind --> 1.1.0.post0      # but we can bring a post component (without pre)
      post --> 1.1.0.post1
       pre --> 1.1.0            # BAD & silent: cannot increment a missing part 
  postkind --> 1.1.0.post0
   prekind --> 1.1.0.dev0       # default: pre part starts at 'dev'
  postkind --> 1.1.0.dev0.post0 # can add post part to a pre part
      post --> 1.1.0.dev0.post1 # etc...
     major --> 2.0.0
   prekind --> 2.0.0.dev0
  postkind --> 2.0.0.dev0.post0
      post --> 2.0.0.dev0.post1
Pierre D
  • 24,012
  • 7
  • 60
  • 96
  • I'm only seeing one issue with this, which is bumping `prekind` isn't quite right because it treats `a`/`alpha` and `b`/`beta` as _sequential_ when it should treat them as _synonyms_. For example, `bump2version prekind` would bump `beta0` -> `b0`. Not sure if there's a way to make `value` recognize tuples of "equal-leveled" version segments. – Brad Solomon Dec 13 '20 at 18:09
  • looking at the code (and running the tests in the debugger), esp. `functions.ValuesFunction` on the master (at your own commit: `2346ff6`!), it doesn't look like any synonym mechanism is provided. It wouldn't be hard to implement, I suppose, and quite useful. Definitions first: probably allow arrays in the list of values that a part can take, instead of simple strings (e.g.: `values: [dev, [a, alpha], [b, beta], ...]`). BTW, one of the most relevant tests for your question is `tests.test_cli.test_python_pre_release_release_post_release`. – Pierre D Dec 17 '20 at 13:24
  • 2
    Yep, I just discovered that test func also. Thanks. Thinking of submitting a PR to allow that type of `values` schema – Brad Solomon Dec 17 '20 at 14:05
  • thx for leading the charge there, @BradSolomon; FWIW, we use `bump2version` extensively for all of our packages, and I'm sure lots of teams around the world do too. I for one am very grateful. – Pierre D Dec 17 '20 at 15:25
  • Is there any way to make this work where you go from prerelease -> release? The way packages are normally released is 0.1.0 -> 0.1.1rc1 -> 0.1.1rc2 -> 0.1.1 (or with other prerelease flags). But you wouldn't go from 1.0.0.rc0 to 0.1.1 as in the example. – Paul Jan 12 '23 at 22:25