29
29
# name of possible repository keys used in image value
30
30
IMAGE_REPOSITORY_KEYS = {"name" , "repository" }
31
31
32
- # prefix in prerelease tag for git commit count
33
- PRERELEASE_PREFIX = "0git."
32
+ # prefixes added to prerelease versions
33
+ # these do not include the trailing '.'
34
+ # which makes them valid prerelease fields on their own,
35
+ # but they cannot be empty.
36
+
37
+ # GIT is always added to start our git info
38
+ GIT_PREFIX = "git"
39
+ # this is the _full_ prefix we add to non-prerelease versions
40
+ PRERELEASE_PREFIX = f"0.dev.{ GIT_PREFIX } "
34
41
35
42
# Container builders
36
43
class Builder (Enum ):
@@ -442,7 +449,7 @@ def _image_needs_building(image, platforms):
442
449
return _image_needs_pushing (image , platforms )
443
450
444
451
445
- def _get_identifier_from_paths (* paths , long = False ):
452
+ def _get_identifier_from_paths (* paths , long = False , base_version = None ):
446
453
latest_commit = _get_latest_commit_tagged_or_modifying_paths (* paths , echo = False )
447
454
448
455
try :
@@ -456,24 +463,29 @@ def _get_identifier_from_paths(*paths, long=False):
456
463
.strip ()
457
464
)
458
465
latest_tag_in_branch , n_commits , sha = git_describe .rsplit ("-" , maxsplit = 2 )
466
+ n_commits = int (n_commits )
467
+ if base_version is None :
468
+ base_version = latest_tag_in_branch
459
469
# remove "g" prefix output by the git describe command
460
470
# ref: https://git-scm.com/docs/git-describe#_examples
461
471
sha = sha [1 :]
462
-
463
- return _get_identifier_from_parts (latest_tag_in_branch , n_commits , sha , long )
464
472
except subprocess .CalledProcessError :
465
473
# no tags on branch, so assume 0.0.1 and
466
474
# calculate n_commits from latest_commit
467
- n_commits = (
475
+ n_commits = int (
468
476
_check_output (
469
477
["git" , "rev-list" , "--count" , latest_commit ],
470
478
echo = False ,
471
479
)
472
480
.decode ("utf-8" )
473
481
.strip ()
474
482
)
483
+ sha = latest_commit
484
+
485
+ if base_version is None :
486
+ base_version = "0.0.1"
475
487
476
- return _get_identifier_from_parts ("0.0.1" , n_commits , latest_commit , long )
488
+ return _get_identifier_from_parts (base_version , n_commits , sha , long )
477
489
478
490
479
491
def _get_identifier_from_parts (tag , n_commits , commit , long ):
@@ -487,25 +499,34 @@ def _get_identifier_from_parts(tag, n_commits, commit, long):
487
499
with h to ensure we don't get a numerical hash starting with 0 because
488
500
those are invalid SemVer 2 versions.
489
501
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`
502
+ If tag is already a prelease, we append fields so we sort later than the prerelease.
503
+ If the tag is a stable release, we start the prerelease with `-0.dev.` to ensure we sort lower
504
+ than labeled prereleases such as 'alpha'.
505
+
506
+ Typical tags in descending order:
507
+
508
+ - 0.1.2
509
+ - 0.1.2-alpha.2
510
+ - 0.1.2-alpha.1.git.5.habc
511
+ - 0.1.2-alpha.1
512
+ - 0.1.2-0.dev.git.3.habc
492
513
493
514
Example:
494
515
tag="0.1.2", n_commits="5", commit="asdf1234", long=True,
495
- should return "0.1.2-0git .5.hasdf1234".
516
+ should return "0.1.2-0.dev.git .5.hasdf1234".
496
517
"""
497
518
n_commits = int (n_commits )
498
519
499
520
if n_commits > 0 or long :
500
521
if "-" in tag :
501
- # add a field to an existing prerelease tag
502
- # 0.1.2-alpha.1 -> 0.1.2-{PRERELEASE_PREFIX}5 .hsha
503
- sep = ". "
522
+ # add fields to an existing prerelease tag
523
+ # 0.1.2-alpha.1 -> 0.1.2-alpha.1.git.n .hsha
524
+ pre = f". { GIT_PREFIX } "
504
525
else :
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 } "
526
+ # create a new '-0.dev.' prerelease tag
527
+ # 0.1.2 -> 0.1.2-0.dev.git. 5.hsha
528
+ pre = f"- { PRERELEASE_PREFIX } "
529
+ return f"{ tag } { pre } . { n_commits } .h{ commit } "
509
530
else :
510
531
return f"{ tag } "
511
532
@@ -522,6 +543,7 @@ def build_images(
522
543
* ,
523
544
builder = Builder .DOCKER_BUILD ,
524
545
platforms = None ,
546
+ base_version = None ,
525
547
):
526
548
"""Build a collection of docker images
527
549
@@ -549,11 +571,11 @@ def build_images(
549
571
550
572
Example 1:
551
573
- long=False: 0.9.0
552
- - long=True: 0.9.0-0git .0.hasdf1234
574
+ - long=True: 0.9.0-0.dev.git .0.hasdf1234
553
575
554
576
Example 2:
555
- - long=False: 0.9.0-0git .4.hsdfg2345
556
- - long=True: 0.9.0-0git .4.hsdfg2345
577
+ - long=False: 0.9.0-0.dev.git .4.hsdfg2345
578
+ - long=True: 0.9.0-0.dev.git .4.hsdfg2345
557
579
558
580
builder (str):
559
581
The container build engine.
@@ -567,7 +589,9 @@ def build_images(
567
589
all_image_paths = _get_all_image_paths (name , options )
568
590
569
591
if tag is None :
570
- image_tag = _get_identifier_from_paths (* all_image_paths , long = long )
592
+ image_tag = _get_identifier_from_paths (
593
+ * all_image_paths , long = long , base_version = base_version
594
+ )
571
595
else :
572
596
image_tag = tag
573
597
@@ -709,23 +733,44 @@ def _update_values_file_with_modifications(name, modifications):
709
733
yaml .dump (values , f )
710
734
711
735
736
+ _suffix_version_pat = re .compile (r"(.*)\.git\.\d+\.h[a-f0-9]+$" )
737
+
738
+
739
+ def _trim_version_suffix (version ):
740
+ """Trim trailing .git... suffix from a version
741
+
742
+ Turns 1.0.0-0.dev.git.5.habc back into 1.0.0-0.dev
743
+ """
744
+ m = _suffix_version_pat .match (version )
745
+ if m :
746
+ # matches, strip suffix
747
+ return m .group (1 )
748
+ return version
749
+
750
+
712
751
def build_chart (
713
- name , version = None , paths = None , long = False , reset = False , strict_version = False
752
+ name ,
753
+ version = None ,
754
+ paths = None ,
755
+ long = False ,
756
+ reset = False ,
757
+ strict_version = False ,
758
+ use_chart_version = False ,
714
759
):
715
760
"""
716
761
Update Chart.yaml's version, using specified version or by constructing one.
717
762
718
763
Chart versions are constructed using:
719
- a) the latest commit that is tagged,
764
+ a) a base version, derived from either Chart.yaml or the latest tag
720
765
b) the latest commit that modified provided paths
721
766
722
767
Example versions constructed:
768
+ - 0.9.0-0.dev.git.2.hdfgh3456
723
769
- 0.9.0-alpha.1
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)
770
+ - 0.9.0-alpha.1.git .0.hasdf1234 (--long)
771
+ - 0.9.0-alpha.1.git .5.hsdfg2345
772
+ - 0.9.0-alpha.1.git .5.hsdfg2345 (--long)
727
773
- 0.9.0
728
- - 0.9.0-0git.2.hdfgh3456
729
774
"""
730
775
# read Chart.yaml
731
776
chart_file = os .path .join (name , "Chart.yaml" )
@@ -734,7 +779,23 @@ def build_chart(
734
779
735
780
# decide a version string
736
781
if version is None :
737
- version = _get_identifier_from_paths (* paths , long = long )
782
+ if use_chart_version :
783
+ # avoid adding .git... to chart version multiple times!
784
+ base_version = _trim_version_suffix (chart ["version" ])
785
+ # TODO: trim -set.by.chartpress?
786
+ # if base_version.endswith("-set.by.chartpress"):
787
+ # base_version = base_version.rsplit("-", 1)[0]
788
+ else :
789
+ base_version = None
790
+ if reset :
791
+ # resetting, use the base version without '.git...'
792
+ version = base_version
793
+ else :
794
+ # derive the full version, with possible '.git...'
795
+ version = _get_identifier_from_paths (
796
+ * paths , long = long , base_version = base_version
797
+ )
798
+
738
799
if not reset :
739
800
version = _fix_chart_version (version , strict = strict_version )
740
801
@@ -1008,10 +1069,16 @@ def main(args=None):
1008
1069
# - push chart (--publish-chart, --extra-message)
1009
1070
for chart in config ["charts" ]:
1010
1071
forced_version = None
1072
+ # TODO: maybe warn and switch default in the future?
1073
+ use_chart_version = chart .get ("useChartVersion" , False )
1074
+
1011
1075
if args .tag :
1076
+ # tag specified, use that version
1012
1077
forced_version = args .tag
1013
- elif args .reset :
1014
- forced_version = chart .get ("resetVersion" , "0.0.1-set.by.chartpress" )
1078
+ elif args .reset and not use_chart_version :
1079
+ # resetting, get version from chrtpress.yaml,
1080
+ # ignoring current version in Chart.yaml
1081
+ forced_version = chart .get ("resetVersion" , "0.0.1-0.dev" )
1015
1082
1016
1083
if not args .list_images :
1017
1084
# update Chart.yaml with a version
@@ -1022,6 +1089,7 @@ def main(args=None):
1022
1089
long = args .long ,
1023
1090
reset = args .reset ,
1024
1091
strict_version = args .publish_chart ,
1092
+ use_chart_version = use_chart_version ,
1025
1093
)
1026
1094
1027
1095
if "images" in chart :
0 commit comments