Skip to content

Commit 5630fc8

Browse files
committed
Make sortable prerelease fields
Instead of `1.2.3-n003.habc` produce `1.2.3-0git.3.habc` - allow fully numerical fields (Leading 0s are only forbidden for numerical fields, not alphanumeric) - prefix with `0git.` to sort before 'alpha'
1 parent 21aad07 commit 5630fc8

File tree

6 files changed

+117
-118
lines changed

6 files changed

+117
-118
lines changed

README.md

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,25 @@ Chartpress will infer chart versions and image tags using a few key pieces of
2525
information.
2626

2727
1. `tag`: If not directly set by `--tag`, it will be inferred from most recent
28-
commit that is tagged in the _current branch_, or be set to 0.0.1 if no
29-
commit is tagged.
28+
commit that is tagged in the _current branch_
29+
(as determined by `git describe`)
30+
or be set to 0.0.1 if no commit is tagged.
3031
1. If the `tag` has a leading `v` but is otherwise a valid
31-
[SemVer2](https://semver.org) version, it will be stripped from Chart.yaml
32+
[SemVer2](https://semver.org) version, the `v` will be stripped from Chart.yaml
3233
before its set as Helm 3 requires Helm chart versions to be SemVer2
3334
compliant.
3435
1. The latest commit modifying content in a _relevant path_ since `tag`.
35-
1. `n`: The latest commit's distance to the tagged commit, described as 3 or
36-
more numbers, prefixed with n.
36+
1. `n`: The number of commits since the tagged commit, as an integer.
3737
1. `h`: The latest commit's abbreviated hash. which is often 7-8 characters,
38-
prefixed with h.
39-
1. If `tag` (like `0.10.0` or `0.10.0-beta.1`) contains a `-`, a `tag.n.h`
40-
format will be used instead of a `tag-n.h` format to be SemVer 2 compliant.
38+
prefixed with `h`.
39+
1. If `tag` (like `0.10.0` or `0.10.0-beta.1`) contains `-`,
40+
indicating that it is a prerelease,
41+
the chartpress suffix will be added to the prerelease fields,
42+
e.g. `0.10.0-beta.1.0git.5.habc123`
43+
format will be used instead of a `tag-0git.n.h` format to be SemVer 2 compliant.
4144
1. If `--long` is specified or not. If `--long` is specified, tagged commits
42-
will be written out with the `n.h` part appended to it, looking something
43-
like `n000.gabcd123`
45+
will always be written out with the `n.h` part appended to it, looking something
46+
like `1.0.0-0git.0.habcd123`
4447

4548
### Examples chart versions and image tags
4649

@@ -49,13 +52,13 @@ order that could come from using chartpress.
4952

5053
```
5154
0.8.0
52-
0.8.0-n004.hasdf123
53-
0.8.0-n010.hsdfg234
55+
0.8.0-0git.4.hasdf123
56+
0.8.0-0git.10.hsdfg234
5457
0.9.0-beta.1
55-
0.9.0-beta.1.n001.hdfgh345
56-
0.9.0-beta.1.n005.hfghj456
58+
0.9.0-beta.1.0git.1.hdfgh345
59+
0.9.0-beta.1.0git.5.hfghj456
5760
0.9.0-beta.2
58-
0.9.0-beta.2.n001.hghjk567
61+
0.9.0-beta.2.0git.1.hghjk567
5962
0.9.0-beta.3
6063
0.9.0
6164
```

chartpress.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
# name of possible repository keys used in image value
3030
IMAGE_REPOSITORY_KEYS = {"name", "repository"}
3131

32+
# prefix in prerelease tag for git commit count
33+
PRERELEASE_PREFIX = "0git."
34+
3235
# Container builders
3336
class Builder(Enum):
3437
DOCKER_BUILD = "docker-build"
@@ -481,24 +484,28 @@ def _get_identifier_from_parts(tag, n_commits, commit, long):
481484
This function should provide valid Helm chart versions, which means they
482485
need to be valid SemVer 2 version strings. It also needs to return valid
483486
image tags, which means they need to not contain `+` signs either. We prefix
484-
with n and h to ensure we don't get a numerical hash starting with 0 because
487+
with h to ensure we don't get a numerical hash starting with 0 because
485488
those are invalid SemVer 2 versions.
486489
490+
We lead with '0git.' to ensure our suffixes sort as older than any explicit tags,
491+
such as `0.1.2-alpha.1 > 0.1.2-alpha.0git.5.habc > 0.1.2-0git.3.h123`
492+
487493
Example:
488494
tag="0.1.2", n_commits="5", commit="asdf1234", long=True,
489-
should return "0.1.2-n005.hasdf1234".
495+
should return "0.1.2-0git.5.hasdf1234".
490496
"""
491497
n_commits = int(n_commits)
492498

493499
if n_commits > 0 or long:
494500
if "-" in tag:
495-
# append a pre-release tag, with a . separator
496-
# 0.1.2-alpha.1 -> 0.1.2-alpha.1.n.h
497-
return f"{tag}.n{n_commits:03d}.h{commit}"
501+
# add a field to an existing prerelease tag
502+
# 0.1.2-alpha.1 -> 0.1.2-{PRERELEASE_PREFIX}5.hsha
503+
sep = "."
498504
else:
499-
# append a release tag, with a - separator
500-
# 0.1.2 -> 0.1.2-n.h
501-
return f"{tag}-n{n_commits:03d}.h{commit}"
505+
# create prerelease tag
506+
# 0.1.2-alpha.1 -> 0.1.2-{PRERELEASE_PREFIX}5.hsha
507+
sep = "-"
508+
return f"{tag}{sep}{PRERELEASE_PREFIX}{n_commits}.h{commit}"
502509
else:
503510
return f"{tag}"
504511

@@ -542,11 +549,11 @@ def build_images(
542549
543550
Example 1:
544551
- long=False: 0.9.0
545-
- long=True: 0.9.0-n000.hasdf1234
552+
- long=True: 0.9.0-0git.0.hasdf1234
546553
547554
Example 2:
548-
- long=False: 0.9.0-n004.hsdfg2345
549-
- long=True: 0.9.0-n004.hsdfg2345
555+
- long=False: 0.9.0-0git.4.hsdfg2345
556+
- long=True: 0.9.0-0git.4.hsdfg2345
550557
551558
builder (str):
552559
The container build engine.
@@ -714,11 +721,11 @@ def build_chart(
714721
715722
Example versions constructed:
716723
- 0.9.0-alpha.1
717-
- 0.9.0-alpha.1.n000.hasdf1234 (--long)
718-
- 0.9.0-alpha.1.n005.hsdfg2345
719-
- 0.9.0-alpha.1.n005.hsdfg2345 (--long)
724+
- 0.9.0-alpha.1.0git.0.hasdf1234 (--long)
725+
- 0.9.0-alpha.1.0git.5.hsdfg2345
726+
- 0.9.0-alpha.1.0git.5.hsdfg2345 (--long)
720727
- 0.9.0
721-
- 0.9.0-n002.hdfgh3456
728+
- 0.9.0-0git.2.hdfgh3456
722729
"""
723730
# read Chart.yaml
724731
chart_file = os.path.join(name, "Chart.yaml")

tests/test_chartpress.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_list_images(git_repo):
2525
assert len(images) == 1
2626
# split hash_suffix which will be different every run
2727
pre_hash, hash_suffix = images[0].rsplit(".", 1)
28-
assert pre_hash == "testchart/testimage:0.0.1-n001"
28+
assert pre_hash == "testchart/testimage:0.0.1-0git.1"
2929

3030
p = run(
3131
["git", "status", "--porcelain"],

tests/test_commands.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from ruamel.yaml import YAML
66

77
import chartpress
8+
from chartpress import PRERELEASE_PREFIX
89

910

1011
@pytest.mark.parametrize("with_args", [False, True])
@@ -78,7 +79,7 @@ def test_build_images(git_repo, mock_check_call, push, tag):
7879
if tag:
7980
expected_tag = tag
8081
else:
81-
expected_tag = f"0.0.1-n001.h{sha[:7]}"
82+
expected_tag = f"0.0.1-{PRERELEASE_PREFIX}1.h{sha[:7]}"
8283

8384
expected_build1 = [
8485
"docker",
@@ -168,7 +169,7 @@ def test_buildx_images(
168169
if tag:
169170
expected_tag = tag
170171
else:
171-
expected_tag = f"0.0.1-n001.h{sha[:7]}"
172+
expected_tag = f"0.0.1-{PRERELEASE_PREFIX}1.h{sha[:7]}"
172173

173174
expected_build1 = [
174175
"docker",
@@ -272,7 +273,7 @@ def test_build_chart(git_repo, mock_check_call, version):
272273
if version:
273274
expected_version = version
274275
else:
275-
expected_version = f"0.0.1-n001.h{sha[:7]}"
276+
expected_version = f"0.0.1-{PRERELEASE_PREFIX}1.h{sha[:7]}"
276277

277278
assert rv == expected_version
278279

tests/test_helpers.py

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,34 @@
22
from ruamel.yaml import YAML
33

44
from chartpress import _check_call
5+
from chartpress import _fix_chart_version
56
from chartpress import _get_git_remote_url
67
from chartpress import _get_identifier_from_parts
78
from chartpress import _get_image_build_args
89
from chartpress import _get_latest_commit_tagged_or_modifying_paths
910
from chartpress import _image_needs_pushing
10-
from chartpress import Builder
1111
from chartpress import GITHUB_ACTOR_KEY
1212
from chartpress import GITHUB_TOKEN_KEY
13+
from chartpress import yaml
1314

14-
# use safe roundtrip yaml loader
15-
yaml = YAML(typ="rt")
16-
yaml.preserve_quotes = True ## avoid mangling of quotes
17-
yaml.indent(mapping=2, offset=2, sequence=4)
1815

19-
20-
def test__get_identifier_from_parts():
21-
assert (
22-
_get_identifier_from_parts(
23-
tag="0.1.2", n_commits="0", commit="asdf123", long=True
24-
)
25-
== "0.1.2-n000.hasdf123"
26-
)
27-
assert (
28-
_get_identifier_from_parts(
29-
tag="0.1.2", n_commits="0", commit="asdf123", long=False
30-
)
31-
== "0.1.2"
32-
)
33-
assert (
34-
_get_identifier_from_parts(
35-
tag="0.1.2", n_commits="5", commit="asdf123", long=False
36-
)
37-
== "0.1.2-n005.hasdf123"
38-
)
39-
assert (
40-
_get_identifier_from_parts(
41-
tag="0.1.2-alpha.1", n_commits="0", commit="asdf1234", long=True
42-
)
43-
== "0.1.2-alpha.1.n000.hasdf1234"
44-
)
45-
assert (
46-
_get_identifier_from_parts(
47-
tag="0.1.2-alpha.1", n_commits="0", commit="asdf1234", long=False
48-
)
49-
== "0.1.2-alpha.1"
50-
)
51-
assert (
52-
_get_identifier_from_parts(
53-
tag="0.1.2-alpha.1", n_commits="5", commit="asdf1234", long=False
54-
)
55-
== "0.1.2-alpha.1.n005.hasdf1234"
16+
@pytest.mark.parametrize(
17+
"tag, n_commits, commit, long, expected",
18+
[
19+
("0.1.2", "0", "asdf123", True, "0.1.2-0git.0.hasdf123"),
20+
("0.1.2", "0", "asdf123", False, "0.1.2"),
21+
("0.1.2", "5", "asdf123", False, "0.1.2-0git.5.hasdf123"),
22+
("0.1.2-alpha.1", "0", "asdf1234", True, "0.1.2-alpha.1.0git.0.hasdf1234"),
23+
("0.1.2-alpha.1", "0", "asdf1234", False, "0.1.2-alpha.1"),
24+
("0.1.2-alpha.1", "5", "asdf1234", False, "0.1.2-alpha.1.0git.5.hasdf1234"),
25+
],
26+
)
27+
def test_get_identifier_from_parts(tag, n_commits, commit, long, expected):
28+
tag = _get_identifier_from_parts(
29+
tag=tag, n_commits=n_commits, commit=commit, long=long
5630
)
31+
assert tag == expected
32+
_fix_chart_version(tag, strict=True)
5733

5834

5935
def test__get_git_remote_url(monkeypatch):

0 commit comments

Comments
 (0)