summaryrefslogtreecommitdiff
path: root/tasks
diff options
context:
space:
mode:
authorBernát Gábor <bgabor8@bloomberg.net>2021-02-14 09:52:21 +0000
committerBernát Gábor <gaborjbernat@gmail.com>2021-02-15 07:52:20 +0000
commitd13f172b37678422bfcdaaa9610b41ac633d5590 (patch)
tree6b262bcb8b4f03ec3ce9aa9982deaeec27433a4e /tasks
parente30fd7466c3bcf4ff3408b2cb6dc46da97ee7d5e (diff)
downloadtox-git-d13f172b37678422bfcdaaa9610b41ac633d5590.tar.gz
Add release task
Signed-off-by: Bernát Gábor <bgabor8@bloomberg.net>
Diffstat (limited to 'tasks')
-rw-r--r--tasks/release.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/tasks/release.py b/tasks/release.py
new file mode 100644
index 00000000..5e739109
--- /dev/null
+++ b/tasks/release.py
@@ -0,0 +1,72 @@
+"""Handles creating a release PR"""
+from pathlib import Path
+from subprocess import check_call
+from typing import Tuple
+
+from git import Commit, Head, Remote, Repo, TagReference
+from packaging.version import Version
+
+ROOT_SRC_DIR = Path(__file__).parents[1]
+
+
+def main(version_str: str) -> None:
+ version = Version(version_str)
+ repo = Repo(str(ROOT_SRC_DIR))
+
+ if repo.is_dirty():
+ raise RuntimeError("Current repository is dirty. Please commit any changes and try again.")
+ upstream, release_branch = create_release_branch(repo, version)
+ release_commit = release_changelog(repo, version)
+ tag = tag_release_commit(release_commit, repo, version)
+ print("push release commit")
+ repo.git.push(upstream.name, release_branch)
+ print("push release tag")
+ repo.git.push(upstream.name, tag)
+ print("All done! ✨ 🍰 ✨")
+
+
+def create_release_branch(repo: Repo, version: Version) -> Tuple[Remote, Head]:
+ print("create release branch from upstream rewrite")
+ upstream = get_upstream(repo)
+ upstream.fetch()
+ branch_name = f"release-{version}"
+ release_branch = repo.create_head(branch_name, upstream.refs.rewrite, force=True)
+ upstream.push(refspec=f"{branch_name}:{branch_name}", force=True)
+ release_branch.set_tracking_branch(repo.refs[f"{upstream.name}/{branch_name}"])
+ release_branch.checkout()
+ return upstream, release_branch
+
+
+def get_upstream(repo: Repo) -> Remote:
+ for remote in repo.remotes:
+ for url in remote.urls:
+ if url.endswith("tox-dev/tox.git"):
+ return remote
+ raise RuntimeError("could not find tox-dev/tox.git remote")
+
+
+def release_changelog(repo: Repo, version: Version) -> Commit:
+ print("generate release commit")
+ check_call(["towncrier", "--yes", "--version", version.public], cwd=str(ROOT_SRC_DIR))
+ release_commit = repo.index.commit(f"release {version}")
+ return release_commit
+
+
+def tag_release_commit(release_commit, repo, version) -> TagReference:
+ print("tag release commit")
+ existing_tags = [x.name for x in repo.tags]
+ if version in existing_tags:
+ print(f"delete existing tag {version}")
+ repo.delete_tag(version)
+ print(f"create tag {version}")
+ tag = repo.create_tag(version, ref=release_commit, force=True)
+ return tag
+
+
+if __name__ == "__main__":
+ import argparse
+
+ parser = argparse.ArgumentParser(prog="release")
+ parser.add_argument("--version", required=True)
+ options = parser.parse_args()
+ main(options.version)