-
Notifications
You must be signed in to change notification settings - Fork 15
/
release.py
executable file
·115 lines (91 loc) · 3.61 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
#!/usr/bin/env python3
# requires toml to be installed
# this tool is specific for poetry projects
import toml
import sys
import subprocess
import argparse
import shlex
def run_cmd(cmd, dry_run=False):
if dry_run:
print(" ".join([shlex.quote(c) for c in cmd]))
return ""
else:
try:
return subprocess.check_output(cmd).decode("utf-8")
except subprocess.CalledProcessError as e:
print(e)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("version", choices=["patch", "minor", "major"])
parser.add_argument(
"-np", "--no-push", help="do not push commits/tags", action="store_true"
)
parser.add_argument(
"-n", "--dry-run", help="only show what would be done", action="store_true"
)
cli_args = parser.parse_args()
run_cmd(["git", "fetch", "--all"], cli_args.dry_run)
status = run_cmd(["git", "status", "-sb"], cli_args.dry_run)
if "behind" in status:
print("Your local branch is behind the remote. Please run `git pull --rebase` first.")
sys.exit(1)
with open("pyproject.toml") as xfp:
cfg = toml.load(xfp)
current_version = cfg["tool"]["poetry"]["version"]
print(f"Current version: {current_version}")
current_version_parts = list(map(int, current_version.split(".")))
if len(current_version_parts) != 3:
print("Version must have three parts!")
sys.exit(1)
if cli_args.version == "patch":
current_version_parts[2] += 1
elif cli_args.version == "minor":
current_version_parts[1] += 1
current_version_parts[2] = 0
elif cli_args.version == "major":
current_version_parts[0] += 1
current_version_parts[1] = 0
current_version_parts[2] = 0
else:
print("Invalid choice for version")
sys.exit(1)
next_version = ".".join(str(p) for p in current_version_parts)
print(f"move to next version inside repo: {next_version}")
# update pyproject.toml
print("update pyproject.toml")
cfg["tool"]["poetry"]["version"] = next_version
if not cli_args.dry_run:
with open("pyproject.toml", "w") as xfp:
toml.dump(cfg, xfp)
# update cfg["tool"]["poetry"]["name"]/__init__.py
init_py = f"""{cfg["tool"]["poetry"]["name"]}/__init__.py"""
content = []
print(f"update {init_py}")
if not cli_args.dry_run:
with open(init_py) as xfp:
for x in xfp.readlines():
if "__version__ = " in x:
x = f"""__version__ = "{next_version}" #\n"""
content.append(x)
with open(init_py, "w") as xfp:
xfp.write("".join(content))
print("committing and pushing to remote")
message = f"move to next version: {next_version}"
run_cmd(["git", "commit", "-a", "-m", message], cli_args.dry_run)
run_cmd(["git", "tag", f"v{next_version}"], cli_args.dry_run)
changelog = run_cmd(["poetry", "run", "gitchangelog"], cli_args.dry_run)
if not cli_args.dry_run:
with open("CHANGELOG.md", "w") as ch:
ch.write(changelog)
run_cmd(["git", "add", "CHANGELOG.md"], cli_args.dry_run)
run_cmd(["git", "commit", "--amend", "--no-edit"], cli_args.dry_run)
# repeat tag for changelog (forced)
run_cmd(["git", "tag", "-f", f"v{next_version}"], cli_args.dry_run)
if not cli_args.no_push:
remotes = run_cmd(["git", "remote"]).rstrip()
for remote in remotes.split("\n"):
run_cmd(["git", "push", remote], cli_args.dry_run)
run_cmd(["git", "push", remote, "--tags"], cli_args.dry_run)
if __name__ == "__main__":
main()