Last active
August 29, 2015 14:06
-
-
Save jbarratt/85c91d7b904462702892 to your computer and use it in GitHub Desktop.
Automated Python Package Releasing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from __future__ import print_function | |
from fabric.api import task, local, env, put | |
import re | |
import fileinput | |
import os | |
import datetime | |
import subprocess | |
import requests | |
import json | |
env.use_ssh_config = True | |
env.hosts = ['ourhost.ourdomain.com'] | |
@task | |
def deploy_docs(): | |
""" | |
Make Sphinx docs and copy them to ourhost.ourdomain.com/docs | |
""" | |
local('make docs') | |
put('docs/_build/html/*', '/var/www/ourpackage/docs/', use_sudo=True) | |
@task | |
def notify_slack(version=None): | |
""" Notify the ctengine slack channel of a new release """ | |
# hardcoded URI from the slack integration panel | |
url = ("https://ourteam.slack.com/services/hooks/incoming-webhook" | |
"?token=tokenid") | |
payload = { | |
'username': 'ourpackage-fabfile', | |
'icon_emoji': ':shipit:', | |
'text': 'Deployed version {} of ourpackage-python'.format(version)} | |
requests.post(url, data=json.dumps(payload)) | |
@task | |
def release(part='patch'): | |
""" Automated software release workflow | |
* (Configurably) bumps the version number | |
* Builds the software | |
* Preloads the correct changelog template for editing | |
* Tags the release | |
* Builds a source distribution | |
* Copies that to the private pypi repo | |
* ships documentation | |
You can run it like:: | |
$ fab release | |
which, by default, will create a 'patch' release (0.0.1 => 0.0.2). | |
You can also specify a patch level (patch, minor, major) to change to:: | |
$ fab release:part=major | |
which will create a 'major' release (0.0.2 => 1.0.0). | |
""" | |
# Dry run 'bumpversion' to find out what the new version number | |
# would be. Useful side effect: exits if the working directory is not | |
# clean. | |
bumpver = subprocess.check_output( | |
['bumpversion', part, '--dry-run', '--verbose'], | |
stderr=subprocess.STDOUT) | |
m = re.search(r'New version will be \'(\d+\.\d+\.\d+)\'', bumpver) | |
version = m.groups(0)[0] | |
date = datetime.date.today().isoformat() | |
# Add the new section for this release we're doing | |
# Using the 'fileinput' module to do inplace editing. | |
for line in fileinput.input(files=['HISTORY.rst'], inplace=1): | |
# by default pass the lines through | |
print(line, end="") | |
# if we just passed through the '-----' line (after the header), | |
# inject a new section for this new release | |
if line.startswith('----'): | |
ver_str = "{} ({})".format(version, date) | |
separator = "".join(["+" for _ in ver_str]) | |
print("\n{}\n{}\n".format(ver_str, separator)) | |
print("* Fill notable features in here\n") | |
# Tries to load the EDITOR environment variable, else falls back to vim | |
editor = os.environ.get('EDITOR', 'vim') | |
os.system("{} HISTORY.rst".format(editor)) | |
# Have to add it so it will be part of the commit | |
subprocess.check_output(['git', 'add', 'HISTORY.rst']) | |
subprocess.check_output( | |
['git', 'commit', '-m', 'Changelog for {}'.format(version)]) | |
# Really run bumpver to set the new release and tag | |
bv_args = ['bumpversion', part] | |
bv_args += ['--new-version', version] | |
subprocess.check_output(bv_args) | |
deploy(version) | |
@task | |
def deploy(version=None): | |
if not version: | |
version = subprocess.check_output(['python', | |
'setup.py', '--version']).strip() | |
# Build the package | |
subprocess.check_output(['python', 'setup.py', 'sdist']) | |
# Copy the package to our web root directory | |
put("dist/ourpackage-{}.tar.gz".format(version), | |
"/var/www/ourpackage/repos/ourpackage/", use_sudo=True) | |
notify_slack(version) | |
# Make docs and place them on ourhost.ourdomain.com/docs | |
deploy_docs() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
replace
with
Its commonly installed and its a speed improvement for json at least.