Skip to content

Instantly share code, notes, and snippets.

@jbarratt
Last active August 29, 2015 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbarratt/85c91d7b904462702892 to your computer and use it in GitHub Desktop.
Save jbarratt/85c91d7b904462702892 to your computer and use it in GitHub Desktop.
Automated Python Package Releasing
#!/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()
@psykzz
Copy link

psykzz commented Sep 7, 2014

replace

import json

with

try:
    import simplejson as json
except: 
    import json

Its commonly installed and its a speed improvement for json at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment