-
Notifications
You must be signed in to change notification settings - Fork 40
/
version-update.py
96 lines (69 loc) · 2.85 KB
/
version-update.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
#!/usr/bin/env python3
import os
import re
import sys
import semver
import subprocess
import gitlab
def git(*args):
return subprocess.check_output(["git"] + list(args))
def verify_env_var_presence(name):
if name not in os.environ:
raise Exception(f"Expected the following environment variable to be set: {name}")
def extract_gitlab_url_from_project_url():
project_url = os.environ['CI_PROJECT_URL']
project_path = os.environ['CI_PROJECT_PATH']
return project_url.split(f"/{project_path}", 1)[0]
def extract_merge_request_id_from_commit():
message = git("log", "-1", "--pretty=%B")
matches = re.search(r'(\S*\/\S*!)(\d+)', message.decode("utf-8"), re.M|re.I)
if matches == None:
raise Exception(f"Unable to extract merge request from commit message: {message}")
return matches.group(2)
def retrieve_labels_from_merge_request(merge_request_id):
project_id = os.environ['CI_PROJECT_ID']
gitlab_private_token = os.environ['NPA_PASSWORD']
gl = gitlab.Gitlab(extract_gitlab_url_from_project_url(), private_token=gitlab_private_token)
gl.auth()
project = gl.projects.get(project_id)
merge_request = project.mergerequests.get(merge_request_id)
return merge_request.labels
def bump(latest):
minor_bump_label = os.environ.get("MINOR_BUMP_LABEL") or "bump-minor"
major_bump_label = os.environ.get("MAJOR_BUMP_LABEL") or "bump-major"
merge_request_id = extract_merge_request_id_from_commit()
labels = retrieve_labels_from_merge_request(merge_request_id)
if minor_bump_label in labels:
return semver.bump_minor(latest)
elif major_bump_label in labels:
return semver.bump_major(latest)
else:
return semver.bump_patch(latest)
def tag_repo(tag):
repository_url = os.environ["CI_REPOSITORY_URL"]
username = os.environ["NPA_USERNAME"]
password = os.environ["NPA_PASSWORD"]
push_url = re.sub(r'([a-z]+://)[^@]*(@.*)', rf'\g<1>{username}:{password}\g<2>', repository_url)
git("fetch", "origin", "refs/tags/*:refs/tags/*", "--prune")
git("remote", "set-url", "--push", "origin", push_url)
git("tag", tag)
git("push", "origin", tag)
def main():
env_list = ["CI_REPOSITORY_URL", "CI_PROJECT_ID", "CI_PROJECT_URL", "CI_PROJECT_PATH", "NPA_USERNAME", "NPA_PASSWORD"]
[verify_env_var_presence(e) for e in env_list]
try:
latest = git("describe", "--tags", "--first-parent", "--match", "[[:digit:]]*.[[:digit:]]*.[[:digit:]]*").decode().strip()
except subprocess.CalledProcessError:
# Default to version 1.0.0 if no tags are available
version = "1.0.0"
else:
# Skip already tagged commits
if '-' not in latest:
print(latest)
return 0
version = bump(latest)
tag_repo(version)
print(version)
return 0
if __name__ == "__main__":
sys.exit(main())