-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrelease.py
executable file
·119 lines (101 loc) · 3.46 KB
/
release.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#! /usr/bin/env python
# This script uses only the standardlib because to make it portable
# and usable from any context (e.g. CI/CD)
import argparse
import os
import subprocess
import sys
from packaging.version import Version, parse
def get_tags(suffix=None):
tags = subprocess.check_output(["git", "tag"]).decode("utf-8")
tags = [t.strip() for t in tags.splitlines()]
if suffix:
tags = [t for t in tags if t.endswith(suffix)]
return tags
def extract_versions(tags):
return sorted(parse(t.split("-", 1)[0]) for t in tags)
def versions(args):
for flavor in sorted(args.flavors):
tags = get_tags(flavor)
versions = extract_versions(tags)
if not versions and not os.path.exists(flavor):
print(f"Flavor not found: {flavor}")
sys.exit(-1)
if args.last:
version = versions[-1]
tag = f"{version}-{flavor}"
print(tag)
if args.push:
remote = args.push
print(f"Pushing tag {tag} to {remote}")
subprocess.check_call(["git", "push", remote, tag])
elif args.next:
if versions:
version = versions[-1]
major, minor, _patch = (
version.major,
version.minor,
version.micro,
)
_patch = 0
if args.next == "minor":
minor += 1
elif args.next == "major":
major += 1
minor = 0
version = Version(f"{major}.{minor}")
else:
version = Version("1.0")
tag = f"{version}-{flavor}"
if args.tag:
print(f"{flavor} => created tag for {version}:\n {tag}")
subprocess.check_call(["git", "tag", tag])
else:
print(tag)
else:
print(flavor)
for version in reversed(versions):
print(version)
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
subparsers = parser.add_subparsers()
parser_versions = subparsers.add_parser(
"versions",
help="Manage versions: either print existing ones, or bump and tag the next one",
)
parser_versions.add_argument(
"--last",
action="store_true",
help="Print the last version(s) without bumping anything",
)
parser_versions.add_argument(
"--next",
choices=["major", "minor", "test"],
default=None,
help="Bump to the next version",
)
parser_versions.add_argument(
"--tag",
action="store_true",
help="Create the git tags (requires --next)",
)
parser_versions.add_argument(
"--push",
help="Push the last tag to the given remote (requires --last), e.g. origin",
)
parser_versions.add_argument(
"flavors", nargs="+", help="Pattern(s) to consider, e.g. py3*"
)
parser_versions.set_defaults(func=versions)
args = parser.parse_args()
if (args.last or args.push) and (args.next or args.tag):
parser.error("Cannot use --last/--push with --next/--tag")
if args.tag and not args.next:
parser.error("Must use --next with --tag")
if args.push and not args.last:
parser.error("Must use --last with --push")
args.func(args)
if __name__ == "__main__":
main()