Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

feat(bump): functionality to add build-metadata to version string #949

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

Merged
merged 1 commit into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions commitizen/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ def __call__(
"help": "bump to the given version (e.g: 1.5.3)",
"metavar": "MANUAL_VERSION",
},
{
"name": ["--build-metadata"],
"help": "Add additional build-metadata to the version-number",
"default": None,
},
],
},
{
Expand Down
13 changes: 13 additions & 0 deletions commitizen/commands/bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def __call__(self): # noqa: C901
is_files_only: bool | None = self.arguments["files_only"]
is_local_version: bool | None = self.arguments["local_version"]
manual_version = self.arguments["manual_version"]
build_metadata = self.arguments["build_metadata"]

if manual_version:
if increment:
Expand All @@ -171,6 +172,11 @@ def __call__(self): # noqa: C901
"--local-version cannot be combined with MANUAL_VERSION"
)

if build_metadata:
raise NotAllowed(
"--build-metadata cannot be combined with MANUAL_VERSION"
)

if major_version_zero:
raise NotAllowed(
"--major-version-zero cannot be combined with MANUAL_VERSION"
Expand All @@ -187,6 +193,12 @@ def __call__(self): # noqa: C901
f"--major-version-zero is meaningless for current version {current_version}"
)

if build_metadata:
if is_local_version:
raise NotAllowed(
"--local-version cannot be combined with --build-metadata"
)

current_tag_version: str = bump.normalize_tag(
current_version,
tag_format=tag_format,
Expand Down Expand Up @@ -235,6 +247,7 @@ def __call__(self): # noqa: C901
prerelease_offset=prerelease_offset,
devrelease=devrelease,
is_local_version=is_local_version,
build_metadata=build_metadata,
)

new_tag_version = bump.normalize_tag(
Expand Down
12 changes: 10 additions & 2 deletions commitizen/commands/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from commitizen.changelog_formats import get_changelog_format
from commitizen.git import GitTag, smart_open
from commitizen.version_schemes import get_version_scheme
from commitizen.cz.utils import strip_local_version


class Changelog:
Expand Down Expand Up @@ -98,7 +99,12 @@ def _find_incremental_rev(self, latest_version: str, tags: list[GitTag]) -> str:
"""
SIMILARITY_THRESHOLD = 0.89
tag_ratio = map(
lambda tag: (SequenceMatcher(None, latest_version, tag.name).ratio(), tag),
lambda tag: (
SequenceMatcher(
None, latest_version, strip_local_version(tag.name)
).ratio(),
tag,
),
tags,
)
try:
Expand Down Expand Up @@ -169,7 +175,9 @@ def __call__(self):
tag_format=self.tag_format,
scheme=self.scheme,
)
start_rev = self._find_incremental_rev(latest_tag_version, tags)
start_rev = self._find_incremental_rev(
strip_local_version(latest_tag_version), tags
)

if self.rev_range:
start_rev, end_rev = changelog.get_oldest_and_newest_rev(
Expand Down
6 changes: 6 additions & 0 deletions commitizen/cz/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from commitizen.cz import exceptions


Expand All @@ -9,3 +11,7 @@ def required_validator(answer, msg=None):

def multiple_line_breaker(answer, sep="|"):
return "\n".join(line.strip() for line in answer.split(sep) if line)


def strip_local_version(version: str) -> str:
return re.sub(r"\+.+", "", version)
17 changes: 16 additions & 1 deletion commitizen/version_schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def bump(
prerelease_offset: int = 0,
devrelease: int | None = None,
is_local_version: bool = False,
build_metadata: str | None = None,
force_bump: bool = False,
) -> Self:
"""
Expand Down Expand Up @@ -191,6 +192,17 @@ def generate_devrelease(self, devrelease: int | None) -> str:

return f"dev{devrelease}"

def generate_build_metadata(self, build_metadata: str | None) -> str:
"""Generate build-metadata

Build-metadata (local version) is not used in version calculations
but added after + statically.
"""
if build_metadata is None:
return ""

return f"+{build_metadata}"

def increment_base(self, increment: str | None = None) -> str:
prev_release = list(self.release)
increments = [MAJOR, MINOR, PATCH]
Expand All @@ -215,6 +227,7 @@ def bump(
prerelease_offset: int = 0,
devrelease: int | None = None,
is_local_version: bool = False,
build_metadata: str | None = None,
force_bump: bool = False,
) -> Self:
"""Based on the given increment a proper semver will be generated.
Expand Down Expand Up @@ -248,6 +261,7 @@ def bump(
if self.minor != 0 or self.micro != 0:
base = self.increment_base(increment)
dev_version = self.generate_devrelease(devrelease)

release = list(self.release)
if len(release) < 3:
release += [0] * (3 - len(release))
Expand All @@ -261,8 +275,9 @@ def bump(
pre_version = base_version.generate_prerelease(
prerelease, offset=prerelease_offset
)
build_metadata = self.generate_build_metadata(build_metadata)
# TODO: post version
return self.scheme(f"{base}{pre_version}{dev_version}") # type: ignore
return self.scheme(f"{base}{pre_version}{dev_version}{build_metadata}") # type: ignore


class Pep440(BaseVersion):
Expand Down
23 changes: 22 additions & 1 deletion docs/bump.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ $ cz bump --help
usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog] [--no-verify] [--yes] [--tag-format TAG_FORMAT]
[--bump-message BUMP_MESSAGE] [--prerelease {alpha,beta,rc}] [--devrelease DEVRELEASE] [--increment {MAJOR,MINOR,PATCH}]
[--check-consistency] [--annotated-tag] [--gpg-sign] [--changelog-to-stdout] [--git-output-to-stderr] [--retry] [--major-version-zero]
[--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {semver,pep440}] [--version-type {semver,pep440}]
[--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {semver,pep440}] [--version-type {semver,pep440}] [--build-metadata BUILD_METADATA]
[MANUAL_VERSION]

positional arguments:
Expand Down Expand Up @@ -95,6 +95,8 @@ options:
choose version scheme
--version-type {semver,pep440}
Deprecated, use --version-scheme
--build-metadata {BUILD_METADATA}
additional metadata in the version string
```

### `--files-only`
Expand Down Expand Up @@ -292,6 +294,25 @@ cz bump --changelog --extra key=value -e short="quoted value"

See [the template customization section](customization.md#customizing-the-changelog-template).

### `--build-metadata`

Provides a way to specify additional metadata in the version string. This parameter is not compatible with `--local-version` as it uses the same part of the version string.

```bash
cz bump --build-metadata yourmetadata
```

Will create a version like `1.1.2+yourmetadata`.
This can be useful for multiple things
* Git hash in version
* Labeling the version with additional metadata.

Note that Commitizen ignores everything after `+` when it bumps the version. It is therefore safe to write different build-metadata between versions.

You should normally not use this functionality, but if you decide to do, keep in mind that
* Version `1.2.3+a`, and `1.2.3+b` are the same version! Tools should not use the string after `+` for version calculation. This is probably not a guarantee (example in helm) even tho it is in the spec.
* It might be problematic having the metadata in place when doing upgrades depending on what tool you use.

## Avoid raising errors

Some situations from commitizen raise an exit code different than 0.
Expand Down
2 changes: 2 additions & 0 deletions tests/commands/test_bump_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,8 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files(
["cz", "bump", "--devrelease", "0", "1.2.3"],
["cz", "bump", "--devrelease", "1", "1.2.3"],
["cz", "bump", "--increment", "PATCH", "1.2.3"],
["cz", "bump", "--build-metadata=a.b.c", "1.2.3"],
["cz", "bump", "--local-version", "--build-metadata=a.b.c"],
],
)
@pytest.mark.usefixtures("tmp_commitizen_project")
Expand Down
47 changes: 47 additions & 0 deletions tests/test_bump_create_commit_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,50 @@ def test_bump_pre_commit_changelog_fails_always(mocker: MockFixture, freezer, re
cmd.run("pre-commit install")
with pytest.raises(exceptions.BumpCommitFailedError):
cli.main()


@pytest.mark.usefixtures("tmp_commitizen_project")
def test_bump_with_build_metadata(mocker: MockFixture, freezer):
def _add_entry(test_str: str, args: list):
Path(test_str).write_text("")
cmd.run("git add -A")
cmd.run(f'git commit -m "fix: test-{test_str}"')
cz_args = ["cz", "bump", "--changelog", "--yes"] + args
mocker.patch.object(sys, "argv", cz_args)
cli.main()

freezer.move_to("2024-01-01")

_add_entry("a", ["--build-metadata", "a.b.c"])
_add_entry("b", [])
_add_entry("c", ["--build-metadata", "alongmetadatastring"])
_add_entry("d", [])

# Pre-commit fixed last line adding extra indent and "\" char
assert Path("CHANGELOG.md").read_text() == dedent(
"""\
## 0.1.4 (2024-01-01)

### Fix

- test-d

## 0.1.3+alongmetadatastring (2024-01-01)

### Fix

- test-c

## 0.1.2 (2024-01-01)

### Fix

- test-b

## 0.1.1+a.b.c (2024-01-01)

### Fix

- test-a
"""
)