diff options
author | Bernát Gábor <bgabor8@bloomberg.net> | 2021-02-14 09:52:21 +0000 |
---|---|---|
committer | Bernát Gábor <gaborjbernat@gmail.com> | 2021-02-15 07:52:20 +0000 |
commit | d13f172b37678422bfcdaaa9610b41ac633d5590 (patch) | |
tree | 6b262bcb8b4f03ec3ce9aa9982deaeec27433a4e /tasks | |
parent | e30fd7466c3bcf4ff3408b2cb6dc46da97ee7d5e (diff) | |
download | tox-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.py | 72 |
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) |