summaryrefslogtreecommitdiff
path: root/tools/finalize.py
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2021-11-12 19:37:53 -0500
committerJason R. Coombs <jaraco@jaraco.com>2021-11-12 19:37:53 -0500
commit26d7411464115c6170ed666e72e388d53d4b7fd2 (patch)
tree40a141e309c856e1af1df3dc2ec7699288d3d384 /tools/finalize.py
parent342e02e7a4dbedf0e3a04c4d2d213b5340d56010 (diff)
parent77678abf97b4a8ee5e6e67b14cb21f543cd6bfd9 (diff)
downloadpython-setuptools-git-feature/local-schemes.tar.gz
Merge branch 'main' into feature/local-schemesfeature/local-schemes
Diffstat (limited to 'tools/finalize.py')
-rw-r--r--tools/finalize.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/tools/finalize.py b/tools/finalize.py
new file mode 100644
index 00000000..516a2fb5
--- /dev/null
+++ b/tools/finalize.py
@@ -0,0 +1,94 @@
+"""
+Finalize the repo for a release. Invokes towncrier and bumpversion.
+"""
+
+__requires__ = ['bump2version', 'towncrier']
+
+
+import subprocess
+import pathlib
+import re
+import sys
+
+
+def release_kind():
+ """
+ Determine which release to make based on the files in the
+ changelog.
+ """
+ # use min here as 'major' < 'minor' < 'patch'
+ return min(
+ 'major' if 'breaking' in file.name else
+ 'minor' if 'change' in file.name else
+ 'patch'
+ for file in pathlib.Path('changelog.d').iterdir()
+ )
+
+
+bump_version_command = [
+ sys.executable,
+ '-m', 'bumpversion',
+ release_kind(),
+]
+
+
+def get_version():
+ cmd = bump_version_command + ['--dry-run', '--verbose']
+ out = subprocess.check_output(cmd, text=True)
+ return re.search('^new_version=(.*)', out, re.MULTILINE).group(1)
+
+
+def update_changelog():
+ cmd = [
+ sys.executable, '-m',
+ 'towncrier',
+ '--version', get_version(),
+ '--yes',
+ ]
+ subprocess.check_call(cmd)
+ _repair_changelog()
+
+
+def _repair_changelog():
+ """
+ Workaround for #2666
+ """
+ changelog_fn = pathlib.Path('CHANGES.rst')
+ changelog = changelog_fn.read_text()
+ fixed = re.sub(r'^(v[0-9.]+)v[0-9.]+$', r'\1', changelog, flags=re.M)
+ changelog_fn.write_text(fixed)
+ subprocess.check_output(['git', 'add', changelog_fn])
+
+
+def bump_version():
+ cmd = bump_version_command + ['--allow-dirty']
+ subprocess.check_call(cmd)
+
+
+def ensure_config():
+ """
+ Double-check that Git has an e-mail configured.
+ """
+ subprocess.check_output(['git', 'config', 'user.email'])
+
+
+def check_changes():
+ """
+ Verify that all of the files in changelog.d have the appropriate
+ names.
+ """
+ allowed = 'deprecation', 'breaking', 'change', 'doc', 'misc'
+ except_ = 'README.rst', '.gitignore'
+ assert all(
+ any(key in file.name for key in allowed)
+ for file in pathlib.Path('changelog.d').iterdir()
+ if file.name not in except_
+ )
+
+
+if __name__ == '__main__':
+ print("Cutting release at", get_version())
+ ensure_config()
+ check_changes()
+ update_changelog()
+ bump_version()