aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGertjan van den Burg <gertjanvandenburg@gmail.com>2020-03-06 15:57:03 +0000
committerGertjan van den Burg <gertjanvandenburg@gmail.com>2020-03-06 15:57:03 +0000
commit877f0e9575c009fbd5c02b26f5cc2068eed598d8 (patch)
tree8ce7b46330ce28b3b753927d5c009bcbf044927e
parentUpdate submodule (diff)
downloadpygensvm-877f0e9575c009fbd5c02b26f5cc2068eed598d8.tar.gz
pygensvm-877f0e9575c009fbd5c02b26f5cc2068eed598d8.zip
Add release script
-rw-r--r--make_release.py268
1 files changed, 268 insertions, 0 deletions
diff --git a/make_release.py b/make_release.py
new file mode 100644
index 0000000..bfb9314
--- /dev/null
+++ b/make_release.py
@@ -0,0 +1,268 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Do-nothing script for making a release
+
+This idea comes from here:
+https://blog.danslimmon.com/2019/07/15/do-nothing-scripting-the-key-to-gradual-automation/
+
+Author: Gertjan van den Burg
+Date: 2019-07-23
+
+"""
+
+import colorama
+import os
+import webbrowser
+
+URLS = {
+ "RTD": "https://readthedocs.org/projects/gensvm/builds/",
+ "Travis": "https://travis-ci.org/GjjvdBurg/PyGenSVM",
+}
+
+
+def colored(msg, color=None, style=None):
+ colors = {
+ "red": colorama.Fore.RED,
+ "green": colorama.Fore.GREEN,
+ "cyan": colorama.Fore.CYAN,
+ "yellow": colorama.Fore.YELLOW,
+ "magenta": colorama.Fore.MAGENTA,
+ None: "",
+ }
+ styles = {
+ "bright": colorama.Style.BRIGHT,
+ "dim": colorama.Style.DIM,
+ None: "",
+ }
+ pre = colors[color] + styles[style]
+ post = colorama.Style.RESET_ALL
+ return f"{pre}{msg}{post}"
+
+
+def cprint(msg, color=None, style=None):
+ print(colored(msg, color=color, style=style))
+
+
+def wait_for_enter():
+ input(colored("\nPress Enter to continue", style="dim"))
+ print()
+
+
+def get_package_name():
+ with open("./setup.py", "r") as fp:
+ nameline = next(
+ (l.strip() for l in fp if l.startswith("NAME = ")), None
+ )
+ return nameline.split("=")[-1].strip().strip('"')
+
+
+class Step:
+ def pre(self, context):
+ pass
+
+ def post(self, context):
+ wait_for_enter()
+
+ def run(self, context):
+ try:
+ self.pre(context)
+ self.action(context)
+ self.post(context)
+ except KeyboardInterrupt:
+ cprint("\nInterrupted.", color="red")
+ raise SystemExit(1)
+
+ def instruct(self, msg):
+ cprint(msg, color="green")
+
+ def print_run(self, msg):
+ cprint("Run:", color="cyan", style="bright")
+ self.print_cmd(msg)
+
+ def print_cmd(self, msg):
+ cprint("\t" + msg, color="cyan", style="bright")
+
+ def do_cmd(self, cmd):
+ cprint(f"Going to run: {cmd}", color="magenta", style="bright")
+ wait_for_enter()
+ os.system(cmd)
+
+
+class GitToMaster(Step):
+ def action(self, context):
+ self.instruct("Make sure you're on master and changes are merged in")
+ self.print_run("git checkout master")
+
+
+class UpdateChangelog(Step):
+ def action(self, context):
+ self.instruct(f"Update change log for version {context['version']}")
+ self.print_run("vi CHANGELOG.md")
+
+
+class RunTests(Step):
+ def action(self, context):
+ self.do_cmd("make test")
+
+
+class BumpVersionPackage(Step):
+ def action(self, context):
+ self.instruct(f"Update __version__.py with new version")
+ self.print_run(f"vi {context['pkgname']}/__version__.py")
+
+ def post(self, context):
+ wait_for_enter()
+ context["version"] = self._get_version(context)
+
+ def _get_version(self, context):
+ # Get the version from the version file
+ about = {}
+ with open(f"{context['pkgname'].lower()}/__version__.py", "r") as fp:
+ exec(fp.read(), about)
+ return about["__version__"]
+
+
+class MakeClean(Step):
+ def action(self, context):
+ self.do_cmd("make clean")
+
+
+class MakeDocs(Step):
+ def action(self, context):
+ self.do_cmd("make docs")
+
+
+class MakeDist(Step):
+ def action(self, context):
+ self.do_cmd("make dist")
+
+
+class PushToTestPyPI(Step):
+ def action(self, context):
+ self.do_cmd(
+ "twine upload --repository-url https://test.pypi.org/legacy/ dist/*"
+ )
+
+
+class InstallFromTestPyPI(Step):
+ def action(self, context):
+ self.print_run("cd /tmp/")
+ self.print_cmd("rm -rf ./venv")
+ self.print_cmd("virtualenv ./venv")
+ self.print_cmd("source ./venv/bin/activate")
+ self.print_cmd(
+ "pip install --index-url https://test.pypi.org/simple/ "
+ + f"--extra-index-url https://pypi.org/simple {context['pkgname']}=={context['version']}"
+ )
+
+
+class TestPackage(Step):
+ def action(self, context):
+ self.instruct(
+ f"Ensure that the following command gives version {context['version']}"
+ )
+ self.print_run(
+ f"python -c 'import {context['pkgname']}; print({context['pkgname']}.__version__)'"
+ )
+
+
+class DeactivateVenv(Step):
+ def action(self, context):
+ self.print_run("deactivate")
+ self.instruct("Go back to the project directory")
+
+
+class GitTagVersion(Step):
+ def action(self, context):
+ self.do_cmd(f"git tag v{context['version']}")
+
+
+class GitTagPreRelease(Step):
+ def action(self, context):
+ self.instruct("Tag version as a pre-release (increment as needed)")
+ self.print_run(f"git tag v{context['version']}-rc.1")
+
+
+class GitAdd(Step):
+ def action(self, context):
+ self.instruct("Add everything to git and commit")
+ self.print_run("git gui")
+
+
+class GitAddRelease(Step):
+ def action(self, context):
+ self.instruct("Add Changelog & Readme to git")
+ self.instruct(
+ f"Commit with title: PyGenSVM Release {context['version']}"
+ )
+ self.instruct("Embed changelog in body commit message")
+ self.print_run("git gui")
+
+
+class PushToPyPI(Step):
+ def action(self, context):
+ self.do_cmd("twine upload dist/*")
+
+
+class PushToGitHub(Step):
+ def action(self, context):
+ self.do_cmd("git push -u --tags origin master")
+
+
+class WaitForTravis(Step):
+ def action(self, context):
+ webbrowser.open(URLS["Travis"])
+ self.instruct(
+ "Wait for Travis to complete and verify that its successful"
+ )
+
+
+class WaitForRTD(Step):
+ def action(self, context):
+ webbrowser.open(URLS["RTD"])
+ self.instruct(
+ "Wait for ReadTheDocs to complete and verify that its successful"
+ )
+
+
+def main():
+ colorama.init()
+ procedure = [
+ GitToMaster(),
+ GitAdd(),
+ MakeClean(),
+ MakeDocs(),
+ RunTests(),
+ PushToGitHub(), # trigger Travis to run tests on all platforms
+ WaitForTravis(),
+ WaitForRTD(),
+ BumpVersionPackage(),
+ GitAdd(),
+ GitTagPreRelease(),
+ PushToGitHub(), # trigger Travis to run tests using cibuildwheel
+ WaitForTravis(),
+ UpdateChangelog(),
+ MakeClean(),
+ MakeDocs(),
+ MakeDist(),
+ PushToTestPyPI(),
+ InstallFromTestPyPI(),
+ TestPackage(),
+ DeactivateVenv(),
+ GitAddRelease(),
+ PushToPyPI(),
+ GitTagVersion(),
+ PushToGitHub(), # triggers Travis to build with cibw and push to PyPI
+ WaitForTravis(),
+ ]
+ context = {}
+ context["pkgname"] = get_package_name()
+ for step in procedure:
+ step.run(context)
+ cprint("\nDone!", color="yellow", style="bright")
+
+
+if __name__ == "__main__":
+ main()