Skip to content

v1.1.1 regression: replace command fails on unapplicable [[tool.bumpversion.files]] directive #331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
kdeldycke opened this issue Mar 31, 2025 · 2 comments
Labels
bug Something isn't working

Comments

@kdeldycke
Copy link
Collaborator

I just stumbled upon a regression when updating from bump-my-version 1.0.2 to 1.1.1.

Working case with 1.0.2

Here is a minimal example to reproduce the issue:

$ mkdir bump-test
$ cd bump-test
$ uv venv
$ source .venv/bin/activate

$ uv pip install "bump-my-version == 1.0.2"
Resolved 28 packages in 3.20s
Prepared 6 packages in 1.03s
Installed 28 packages in 47ms
 + annotated-types==0.7.0
 + anyio==4.9.0
 + bracex==2.5.post1
 + bump-my-version==1.0.2
 + certifi==2025.1.31
 + click==8.1.8
 + exceptiongroup==1.2.2
 + h11==0.14.0
 + httpcore==1.0.7
 + httpx==0.28.1
 + idna==3.10
 + markdown-it-py==3.0.0
 + mdurl==0.1.2
 + prompt-toolkit==3.0.50
 + pydantic==2.11.1
 + pydantic-core==2.33.0
 + pydantic-settings==2.8.1
 + pygments==2.19.1
 + python-dotenv==1.1.0
 + questionary==2.1.0
 + rich==14.0.0
 + rich-click==1.8.8
 + sniffio==1.3.1
 + tomlkit==0.13.2
 + typing-extensions==4.13.0
 + typing-inspection==0.4.0
 + wcmatch==10.0
 + wcwidth==0.2.13

$ bump-my-version --version
bump-my-version, version 1.0.2

Now let's work on that minimal project:

$ cat ./pyproject.toml
[project]
version = "4.15.6"

[tool.bumpversion]
current_version = "4.15.6"
allow_dirty = true
ignore_missing_files = true

[[tool.bumpversion.files]]
# Update the version in Markdown changelog.
filename = "./changelog.md"
search = "## [{current_version} (unreleased)]("
replace = "## [{new_version} (unreleased)]("
$ cat ./changelog.md
# Changelog

## [4.15.6 (unreleased)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

> [!IMPORTANT]
> This version is not released yet and is under active development.

Running the following command works as intended with v1.0.2:

$ bump-my-version replace --verbose --no-configured-files --search " (unreleased)" --replace " ({utcnow:%Y-%m-%d})" ./changelog.md
Starting BumpVersion 1.0.2
Reading configuration
  Reading config file: /Users/kde/code/bump-test/pyproject.toml

File ./changelog.md: replace ` (unreleased)` with ` ({utcnow:%Y-%m-%d})`
  Found '\ \(unreleased\)' at line 3:  (unreleased)
  Changing file ./changelog.md:
    *** before ./changelog.md
    --- after ./changelog.md
    ***************
    *** 1,6 ****
      # Changelog

    ! ## [4.15.6 (unreleased)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

      > [!IMPORTANT]
      > This version is not released yet and is under active development.
    --- 1,6 ----
      # Changelog

    ! ## [4.15.6 (2025-03-31)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

      > [!IMPORTANT]
      > This version is not released yet and is under active development.

File ./changelog.md: replace ` (unreleased)` with ` ({utcnow:%Y-%m-%d})`
  Found '4\.15\.6' at line 3: 4.15.6
  Not changing file ./changelog.md

And you can see there that the (unreleased) string was replaced with the current date.

Regression with 1.1.1

Now let's update to the latest version of bump-my-version:

$ uv pip install "bump-my-version == 1.1.1"
Resolved 28 packages in 655ms
Prepared 1 package in 353ms
Uninstalled 1 package in 7ms
Installed 1 package in 7ms
 - bump-my-version==1.0.2
 + bump-my-version==1.1.1

$ bump-my-version --version
bump-my-version, version 1.1.1

In the same conditions, with the same files, the command fails with the following error:

$ bump-my-version replace --verbose --no-configured-files --search " (unreleased)" --replace " ({utcnow:%Y-%m-%d})" ./changelog.md
Starting BumpVersion 1.1.1
Reading configuration
  Reading config file: /Users/kde/code/bump-test/pyproject.toml

File ./changelog.md: replace ` (unreleased)` with ` ({utcnow:%Y-%m-%d})`
  Found '\ \(unreleased\)' at line 3:  (unreleased)
  Changing file ./changelog.md:
    *** before ./changelog.md
    --- after ./changelog.md
    ***************
    *** 1,6 ****
      # Changelog

    ! ## [4.15.6 (unreleased)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

      > [!IMPORTANT]
      > This version is not released yet and is under active development.
    --- 1,6 ----
      # Changelog

    ! ## [4.15.6 (2025-03-31)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

      > [!IMPORTANT]
      > This version is not released yet and is under active development.

File ./changelog.md: replace ` (unreleased)` with ` ({utcnow:%Y-%m-%d})`

 Usage: bump-my-version replace [OPTIONS] [FILES]...

 Try 'bump-my-version replace -h' for help
╭─ Error ───────────────────────────────────────────────────────╮
│ Did not find ' (unreleased)' in file: './changelog.md'        │
╰───────────────────────────────────────────────────────────────╯

In this case you can see that the (unreleased) string was replaced with the current date, but bump-my-version stumble upon the [[tool.bumpversion.files]] directive from the pyproject.toml file, which is simply ignored in the case of version 1.0.2.

To prove my point, removing the [[tool.bumpversion.files]] directive from the pyproject.toml file makes the command work again:

cat ./pyproject.toml
[project]
version = "4.15.6"

[tool.bumpversion]
current_version = "4.15.6"
allow_dirty = true
ignore_missing_files = true
$ bump-my-version replace --verbose --no-configured-files --search " (unreleased)" --replace " ({utcnow:%Y-%m-%d})" ./changelog.md
Starting BumpVersion 1.1.1
Reading configuration
  Reading config file: /Users/kde/code/bump-test/pyproject.toml

File ./changelog.md: replace ` (unreleased)` with ` ({utcnow:%Y-%m-%d})`
  Found '\ \(unreleased\)' at line 3:  (unreleased)
  Changing file ./changelog.md:
    *** before ./changelog.md
    --- after ./changelog.md
    ***************
    *** 1,6 ****
      # Changelog

    ! ## [4.15.6 (unreleased)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

      > [!IMPORTANT]
      > This version is not released yet and is under active development.
    --- 1,6 ----
      # Changelog

    ! ## [4.15.6 (2025-03-31)](https://github.com/kdeldycke/workflows/compare/v4.15.5...main)

      > [!IMPORTANT]
      > This version is not released yet and is under active development.
@kdeldycke kdeldycke changed the title 1.1.1 regression: replace command fails on unapplicable [[tool.bumpversion.files]] directive v1.1.1 regression: replace command fails on unapplicable [[tool.bumpversion.files]] directive Mar 31, 2025
@kdeldycke kdeldycke added the bug Something isn't working label Mar 31, 2025
@kdeldycke
Copy link
Collaborator Author

With additional testing, v1.1.0 behave the same way as v1.0.2. So the regression was introduced in v1.1.1.

kdeldycke added a commit to kdeldycke/workflows that referenced this issue Mar 31, 2025
@coordt
Copy link
Member

coordt commented Mar 31, 2025

This is a known issue, but one I'm not sure there is a fix for.

This "regression" appears to be due to the fix of another bug #321 .

This behavior is caused by a conflict between --no-configured-files flag and the wish to change a file that has a configuration. The flag is file-based, not change-based, so you are trying to exclude and include the same file, even though the changes are different.

I intentionally left this "regression" feeling that it was the lesser of two bugs and the logic was sound based on the file-based granularity.

The original tool's file-based granularity is a legacy, and it might be time to adapt to a change-based granularity. I would make that new behavior, though.

Thoughts?

(Also, thanks for the time taken to make a very thorough bug report)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants