Skip to content

Commit

Permalink
Merge pull request #230 from manics/autoincrement-baseversion
Browse files Browse the repository at this point in the history
Autoincrement base version from tag if not specified
  • Loading branch information
consideRatio authored Jan 9, 2024
2 parents 9a5fbea + f201450 commit bfc98fd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 21 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ charts:
# Recommended together with a version-bumping tool like `tbump`.
# if baseVersion is not a prerelease version (no -suffix),
# the suffix `-0.dev` will be appended.
#
# Alternatively baseVersion can be set to "major", "minor", or "patch", then
# baseVersion will be calculated based on the latest version tag from `git
# describe`, but have its "major", "minor", or "patch" version increment if
# the version isn't a pre-release.
baseVersion: 3.2.1-0.dev

# The git repo whose gh-pages contains the charts. This can be a local
Expand Down
63 changes: 45 additions & 18 deletions chartpress.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,15 +989,54 @@ def publish_pages(
_check_call(["git", "push", "origin", "gh-pages"], cwd=checkout_dir)


def _check_base_version(base_version):
def _increment_semver(version, field):
"""Increment a semver (major,minor,patch) tuple in the specified field"""
if field == "major":
return (version[0] + 1, 0, 0)
if field == "minor":
return (version[0], version[1] + 1, 0)
if field == "patch":
return (version[0], version[1], version[2] + 1)
raise ValueError(f"field must be one of major, minor, patch, not {field}")


def _check_or_get_base_version(base_version):
"""Verify that a baseVersion config is valid
If specified, base version needs to:
1. be a valid semver prerelease
2. sort after the latest tag on the branch
If specified, base version needs to be either:
- a valid semver prerelease that sorts after the latest tag on the branch
- a string "major" "minor" "patch" to indicate the base version is the latest
tag incremented in the specified field
"""

def _version_number(groups):
"""Return comparable semver"""

return (
int(groups["major"]),
int(groups["minor"]),
int(groups["patch"]),
)

tag, count = _get_latest_tag_and_count()
if tag:
tag_match = _semver2.fullmatch(tag.lstrip("v"))
if tag_match:
tag_version_number = _version_number(tag_match.groupdict())

if base_version in ("major", "minor", "patch"):
if not tag:
return "0.0.1-0.dev"
if not tag_match:
raise ValueError(
f"baseVersion {base_version} is not valid when latest tag {tag} is not semver"
)
if "-" in tag:
# If this is a prerelease we shouldn't need to increment anything
return tag
new_base_version = _increment_semver(tag_version_number, base_version)
return "{}.{}.{}-0.dev".format(*new_base_version)

if "-" not in base_version:
# config version is a stable release,
# append default '-0.dev' so we always produce a prerelease
Expand All @@ -1010,24 +1049,12 @@ def _check_base_version(base_version):
)
base_version_groups = match.groupdict()

def _version_number(groups):
"""Return comparable semver"""

return (
int(groups["major"]),
int(groups["minor"]),
int(groups["patch"]),
)

# check ordering with latest tag
# do not check on a tagged commit
tag, count = _get_latest_tag_and_count()
if tag and count:
tag_match = _semver2.fullmatch(tag.lstrip("v"))
sort_error = f"baseVersion {base_version} is not greater than latest tag {tag}. Please update baseVersion config in chartpress.yaml."
if tag_match:
base_version_number = _version_number(base_version_groups)
tag_version_number = _version_number(tag_match.groupdict())
if base_version_number < tag_version_number:
raise ValueError(sort_error)
elif base_version_number == tag_version_number:
Expand Down Expand Up @@ -1208,7 +1235,7 @@ def main(argv=None):
# (e.g. forgetting to update after release)
base_version = chart.get("baseVersion", None)
if base_version:
base_version = _check_base_version(base_version)
base_version = _check_or_get_base_version(base_version)

if not args.list_images:
# update Chart.yaml with a version
Expand Down
18 changes: 15 additions & 3 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,29 @@ def test__get_image_extra_build_command_options(git_repo):
("1.2.3-0.dev", "2.0.0", 0, "1.2.3-0.dev"),
# ignore invalid semver tags
("1.2.3-0.dev", "x.y.z", 10, "1.2.3-0.dev"),
# autoincrement latest tag
("major", "1.2.3", 10, "2.0.0-0.dev"),
("minor", "1.2.3", 10, "1.3.0-0.dev"),
("patch", "1.2.3", 10, "1.2.4-0.dev"),
("patch", None, 10, "0.0.1-0.dev"),
(
"patch",
"x.y.z",
10,
ValueError("not valid when latest tag x.y.z is not semver"),
),
("patch", "1.2.3-beta.1", 10, "1.2.3-beta.1"),
],
)
def test_check_base_version(base_version, tag, n_commits, result):
def test_check_or_get_base_version(base_version, tag, n_commits, result):
with mock.patch.object(
chartpress, "_get_latest_tag_and_count", lambda: (tag, n_commits)
):
if isinstance(result, Exception):
with pytest.raises(result.__class__) as exc:
chartpress._check_base_version(base_version)
chartpress._check_or_get_base_version(base_version)
assert str(result) in str(exc)
assert base_version in str(exc)
else:
used_version = chartpress._check_base_version(base_version)
used_version = chartpress._check_or_get_base_version(base_version)
assert used_version == result

0 comments on commit bfc98fd

Please sign in to comment.