-
Notifications
You must be signed in to change notification settings - Fork 10
/
release.py
137 lines (115 loc) · 4.36 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
from datetime import date
import re
import shutil
import subprocess
import sys
import tempfile
import urllib
REPO = "HactarCE/Hyperspeedcube"
# Shamelessly stolen from https://stackoverflow.com/a/31499114/4958484
# Modified so as not to keep file attributes, such as modification time
def sed_inplace(filename, pattern, repl):
''',
Perform the pure-Python equivalent of in-place `sed` substitution: e.g.,
`sed -i -e 's/'${pattern}'/'${repl}' "${filename}"`.
''',
# For efficiency, precompile the passed regular expression.
pattern_compiled = re.compile(pattern)
# For portability, NamedTemporaryFile() defaults to mode "w+b" (i.e., binary
# writing with updating). This is usually a good thing. In this case,
# however, binary writing imposes non-trivial encoding constraints trivially
# resolved by switching to text writing. Let's do that.
with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file:
with open(filename) as src_file:
for line in src_file:
tmp_file.write(pattern_compiled.sub(repl, line))
# Overwrite the original file with the munged temporary file.
shutil.move(tmp_file.name, filename)
def do_subcommand(name):
return len(sys.argv) == 1 or name in sys.argv[1:]
print("Please make sure your working directory is clean before proceeding.")
print()
print("Available subcommands: write, git, release-url")
print()
version = input("Enter new version number: v") or exit(1)
if do_subcommand('git'):
branch = input("Enter current git branch: ") or exit(1)
if do_subcommand('write'):
# Set package `version`.
sed_inplace('Cargo.toml',
r'^version = "[^"\n]*"$',
f'version = "{version}"')
# Set Windows metadata `ProductVersion`.
sed_inplace('Cargo.toml',
r'^ProductVersion = "[^"]*"$',
f'ProductVersion = "{version}"')
# Set environment variable `HYPERSPEEDCUBE_VERSION` in GitHub Actions workflow.
sed_inplace('.github/workflows/builds.yml',
r'HYPERSPEEDCUBE_VERSION: .*',
f'HYPERSPEEDCUBE_VERSION: {version}')
# Set latest version in changelog.
sed_inplace('CHANGELOG.md',
r'\[UNRELEASED\]',
f'[{version}] - {date.today():%Y-%m-%d}')
# Update Cargo.lock
subprocess.run(['cargo', 'update', '--workspace'], check=True)
if do_subcommand('git'):
git_commands = [
f'git add Cargo.toml Cargo.lock .github/workflows CHANGELOG.md',
f'git commit -m "Version {version}"',
f'git push',
f'git tag v{version}',
f'git push origin refs/tags/v{version}',
f'git checkout stable',
f'git merge refs/tags/v{version}',
f'git push',
]
if branch != 'patch':
git_commands += [
f'git checkout patch',
f'git merge refs/tags/v{version}',
f'git push',
]
if branch != 'main':
git_commands += [
f'git checkout main',
f'git merge refs/tags/v{version}',
f'git push',
]
if branch != 'dev':
git_commands += [
f'git checkout dev',
f'git merge refs/tags/v{version}',
f'git push',
]
git_commands += [f'git checkout {branch}']
print("Updated version numbers in Cargo.toml, GitHub Actions workflow, and changelog. Next steps:")
print()
for cmd in git_commands:
print(' ' + cmd)
print()
print("Press enter to run these commands, or ctrl+C to cancel.")
input()
for cmd in git_commands:
subprocess.run(cmd, shell=True, check=True)
print("Success!")
if do_subcommand('release-url'):
with open('CHANGELOG.md') as f:
changelog_body = re.search(
rf'## \[{version}\].*\n((\n|[^#\n].*\n|###.*\n)*)',
f.read(),
).group(1)
with open('tmp_release_notes.txt', 'w') as f:
f.write(
changelog_body.strip()
+ f"\n\n**[Changelog](https://github.com/{REPO}/blob/main/CHANGELOG.md)**\n"
)
print("Click this link to make the release:")
print(
f"https://github.com/{REPO}/releases/new"
f"?tag=v{version}"
f"&title=v{version}"
# f"&body=**%5BChangelog%5D(https://github.com/{REPO}/blob/main/CHANGELOG.md)**"
)
print("See tmp_release_notes.txt for release body")