Skip to content

fix(version): recognize PEP 440 development tags - #2026

Open
ychampion wants to merge 1 commit into
commitizen-tools:masterfrom
ychampion:fix/pep440-devrelease-tags
Open

fix(version): recognize PEP 440 development tags#2026
ychampion wants to merge 1 commit into
commitizen-tools:masterfrom
ychampion:fix/pep440-devrelease-tags

Conversation

@ychampion

Copy link
Copy Markdown

Description

Fixes #1367.

The default $version parser rejected .devN tags that Commitizen itself creates. This keeps generated PEP 440 prerelease, development, and local-version combinations discoverable so the next incremental changelog can find the previous tag.

Checklist

Was generative AI tooling used to co-author this PR?

  • Yes (OpenAI Codex)

Generated-by: OpenAI Codex following the guidelines

Code Changes

  • Added regression coverage for the parser and sequential uv-provider bumps
  • Ran uv run poe all locally
  • Manually reproduced two sequential development bumps with incremental changelogs
  • Verified existing PEP 440, SemVer, custom tag-format, and invalid-tag coverage
  • Documentation is unchanged because no option or workflow changed

Expected Behavior

After creating 0.2.0.dev0, a subsequent --devrelease 1 bump should recognize that tag and generate the 0.2.0.dev1 changelog, tag, pyproject.toml, and uv.lock updates.

Steps to Test This Pull Request

  1. Configure the uv version provider with update_changelog_on_bump and changelog_incremental enabled.
  2. Run cz bump --devrelease 0 --yes after a feature commit.
  3. Add another feature commit and run cz bump --devrelease 1 --yes.
  4. Confirm the second bump succeeds and writes 0.2.0.dev1 to the tag, changelog, pyproject.toml, and uv.lock.

Keep development-release tags discoverable across sequential bumps while preserving custom tag embedding and existing suffix behavior.

Constraint: Preserve custom tag formats and SemVer-compatible parsing.

Rejected: Replace the shared parser with the anchored PEP 440 reference regex | it breaks embedded tag formats and unrelated schemes.

Confidence: high

Scope-risk: narrow

Directive: Keep generated version forms round-trippable through TagRules.

Tested: uv run poe all; 446 focused tag, version, bump, and changelog tests; exact uv-provider sequential bump regression; git diff --check.

Not-tested: Full tox matrix across every supported Python version and operating system.
@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.23%. Comparing base (7812abe) to head (bca8975).
⚠️ Report is 34 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2026   +/-   ##
=======================================
  Coverage   98.23%   98.23%           
=======================================
  Files          61       61           
  Lines        2784     2784           
=======================================
  Hits         2735     2735           
  Misses         49       49           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@Manny7717 Manny7717 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.

bca8975

Verified locally against head bca897506ad1242431ac6365347f62fd694015e0 (commitizen master + this PR's 3 files):

  • Regression proven: on master's code, TagRules().is_version_tag("0.2.0.dev0") is False and extract_version raises InvalidVersion — same for 0.2.0.dev0+build.1, 0.2.0a1.dev0, 0.2.0a1.dev0+build.1, 2.0.0.dev0, and 1.2.3rc1+build5. With this PR all parse correctly; the new test_is_version_tag_accepts_pep440_devrelease fails on master and passes here.
  • No regressions (differential battery, 15 tags incl. 1.2.3, v1.2.3, 1.2.3rc1, 1.2.3-dev1, 1.2.3+build.1, 0.2.0dev0, 0.1.0): every tag recognized on master is recognized identically here; 0.2.0.not-a-release stays rejected. The change is strictly additive — it only accepts previously-rejected valid PEP 440 forms.
  • Group numbering unchanged ((\w+)?(?:\w+)?, build group was never captured), so nothing referencing the old groups breaks.
  • Tests: tests/test_tags.py + tests/test_version_schemes.py = 16 passed; test_bump_command.py::test_bump_devrelease_with_incremental_changelog passes (exercises two real bump --devrelease runs incl. uv-provider version sync + incremental changelog); ruff clean on all touched files.

One non-blocking nit: the dotless forms (0.2.0dev0) normalize correctly via packaging, but the new test's 0.2.0.dev0+build.1 round-trip depends on str(Version) normalization — worth keeping in mind if a custom tag_format ever needs the literal string preserved. Not a blocker.

Fix is correct, minimal, and well-tested — approving.

注册 for free to join this conversation on GitHub. Already have an account? 登录 to comment

项目

None yet

Development

Successfully merging this pull request may close these issues.

The --devrelease option in cz bump is not correctly incrementing the version

2 participants