Skip to content

Commit

Permalink
Add initial release script
Browse files Browse the repository at this point in the history
  • Loading branch information
dhleong committed Aug 28, 2019
1 parent 22c1061 commit 997bcbe
Showing 1 changed file with 149 additions and 0 deletions.
149 changes: 149 additions & 0 deletions release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env python
#
# Release script for spade
#

from collections import OrderedDict

try:
from hostage import * #pylint: disable=unused-wildcard-import,wildcard-import
except ImportError:
print "!! Release library unavailable."
print "!! Use `pip install hostage` to fix."
print "!! You will also need an API token in .github.token,"
print "!! a .hubrrc config, or `brew install hub` configured."
print "!! A $GITHUB_TOKEN env variable will also work."
exit(1)

#
# Globals
#

notes = File(".last-release-notes")
latestTag = git.Tag.latest()

def formatIssue(issue):
return "- {title} (#{number})\n".format(
number=issue.number,
title=issue.title)

def buildLabeled(labelsToTitles):
"""Given a set of (label, title) tuples, produces an
OrderedDict whose keys are `label`, and whose values are
dictionaries containing 'title' -> `title`, and
'content' -> string. The iteration order of the dictionary
will preserve the ordering of the provided tuples
"""
result = OrderedDict()
for k, v in labelsToTitles:
result[k] = {'title': v, 'content': ''}
return result

def buildDefaultNotes(_):
if not latestTag: return ''

logParams = {
'path': latestTag.name + "..HEAD",
'grep': ["Fix #", "Fixes #", "Closes #"],
'pretty': "format:- %s"}
logParams["invertGrep"] = True
msgs = git.Log(**logParams).output()

contents = ''

lastReleaseDate = latestTag.get_created_date()
if lastReleaseDate.tzinfo:
# pygithub doesn't respect tzinfo, so we have to do it ourselves
lastReleaseDate -= lastReleaseDate.tzinfo.utcoffset(lastReleaseDate)
lastReleaseDate.replace(tzinfo=None)

closedIssues = github.find_issues(state='closed', since=lastReleaseDate)

labeled = buildLabeled([
['feature', "New Features"],
['enhancement', "Enhancements"],
['bug', "Bug Fixes"],
['_default', "Other resolved tickets"],
])

if closedIssues:
for issue in closedIssues:
found = False
for label in labeled.iterkeys():
if label in issue.labels:
labeled[label]['content'] += formatIssue(issue)
found = True
break
if not found:
labeled['_default']['content'] += formatIssue(issue)

for labeledIssueInfo in labeled.itervalues():
if labeledIssueInfo['content']:
contents += "\n**{title}**:\n{content}".format(**labeledIssueInfo)

if msgs: contents += "\n**Notes**:\n" + msgs
return contents.strip()

#
# Verify
#

version = verify(File("project.clj")
.filtersTo(RegexFilter('defproject net.dhleong/spade "(.*)"'))
).valueElse(echoAndDie("No version!?"))
if version.endswith("SNAPSHOT"):
print "May not release SNAPSHOT versions (got %s)" % version
sys.exit(1)
else:
print version

versionTag = git.Tag(version)

verify(versionTag.exists())\
.then(echoAndDie("Version `%s` already exists!" % version))

#
# Make sure all the tests pass
#

verify(Execute("lein test")).succeeds(silent=False).orElse(die())

#
# Build the release notes
#

initialNotes = verify(notes.contents()).valueElse(buildDefaultNotes)
notes.delete()

verify(Edit(notes, withContent=initialNotes).didCreate())\
.orElse(echoAndDie("Aborted due to empty message"))

releaseNotes = notes.contents()

#
# Deploy
#

verify(Execute('lein deploy clojars')).succeeds(silent=False)

#
# Upload to github
#

print "Uploading to Github..."

verify(versionTag).create()
verify(versionTag).push("origin")

gitRelease = github.Release(version)
verify(gitRelease).create(body=releaseNotes)

#
# Success! Now, just cleanup and we're done!
#

notes.delete()

print "Done! Published %s" % version

# flake8: noqa

0 comments on commit 997bcbe

Please sign in to comment.