Skip to content

Instantly share code, notes, and snippets.

@glensc
Last active January 31, 2017 14:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save glensc/f2c8a482bda04981d76b to your computer and use it in GitHub Desktop.
Save glensc/f2c8a482bda04981d76b to your computer and use it in GitHub Desktop.
Subversion integration with Slack
#!/usr/bin/python
# Script for Subversion integration with Slack
#
# Uses slackweb module:
# https://github.com/satoshi03/slack-python-webhook
# 1. Save this file in /usr/bin as slack-svn-hook
# 2. Make it executable:
# chmod +x /usr/bin/slack-svn-hook
# 3. Put this line at the end of file of your_svn_repo/hooks/post-commit:
# slack-svn-hook $REPOS $REV
# 4. Edit this file set your token and params (example given is for Trac)
#
# Refs:
# - https://slack.com/services/new/incoming-webhook
# - https://gist.github.com/amree/8a12037a731bc4893d76
# - https://github.com/chriseldredge/git-slack-hook/blob/master/git-slack-hook
# - http://svnbook.red-bean.com
# - https://api.slack.com/docs/attachments
# Get token from https://my.slack.com/services/new/incoming-webhook
HOOK_URL = 'https://hooks.slack.com/services/...'
# URL To Trac environment
TRAC_URL = 'https://trac.example.org'
# URL to Ticket system, use None to disable
ISSUE_URL = 'https://eventum.example.org/view.php?id=%(issue_id)s'
# URL to Jira, use None to disable
JIRA_URL = "https://jira.example.org/browse/%(issue_key)s"
# "#channel" or "@nick" to post to
CHANNEL = '@glen'
# Username to show in webook
USERNAME = 'SVN Commit'
import sys
import re
import subprocess
import slackweb
def svnlook(args, rev=None, repos=None):
command = [ 'svnlook' ]
command.append(args)
if rev:
command.append('-r %s' % rev)
if repos:
command.append(repos)
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = p.communicate(None)
p.wait()
if err:
print >> sys.stderr, "%s: %s" % (sys.argv[0], err)
sys.exit(1)
return out.strip()
# process text for extra markup
def process_text(s):
if ISSUE_URL:
def repl(m):
url = ISSUE_URL % m.groupdict()
return "<%s|%s>" % (url, m.group(0))
s = re.sub('(?i)(?:issue|bug) ?:? ?#?(?P<issue_id>\d+)', repl, s)
if JIRA_URL:
def repl(m):
url = JIRA_URL % m.groupdict()
return "<%s|%s>" % (url, m.group(0))
s = re.sub("(?P<issue_key>[A-Z]+-\d+)", repl, s)
def cs_repl(m):
params = m.groupdict()
params['url'] = TRAC_URL
url = "%(url)s/changeset/%(rev)s" % params
return "<%s|%s>" % (url, m.group(0))
s = re.sub('[r\[](?P<rev>\d+)\]?', cs_repl, s)
return s
if len(sys.argv) < 3:
print "Usage: %s REPOS REV" % (sys.argv[0])
sys.exit(1)
repos, rev = sys.argv[1:]
author = svnlook("author", rev=rev, repos=repos)
commit_msg = process_text(svnlook("log", rev=rev, repos=repos))
# fallback is used as Desktop Notification, keep it short
fallback = "r%s by %s: %s..." % (rev, author, commit_msg[0:24])
# value is rich formatted commit message
value = "<%s/changeset/%s|r%s> %s" % (TRAC_URL, rev, rev, commit_msg)
attachments = []
attachment = {
"fallback": fallback,
"color": "good",
"fields": [
{ "title" : author, "value" : value },
],
}
attachments.append(attachment)
slack = slackweb.Slack(url=HOOK_URL)
slack.notify(attachments=attachments, channel=CHANNEL, username=USERNAME)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment