Linking Subversion Commits to Pivotal Tracker on Windows using Powershell
Posted by Dylan Beattie on 24 June 2013 • permalinkMy team at work now keep our entire lives in PivotalTracker, and rather like it. We recently linked it to our GitHub repository using the built-in PivotalTracker integration that’s provided by GitHub, which worked really nicely. Thing is, we’re still in the process of migrating our codebase to GitHub – there’s lots of older projects with TeamCity jobs still linked to our in-house Subversion repo – and I wanted to add a similar facility for our projects that are still in Subversion.
This is all based on the Source Control Management Post-Commit Hook Integration feature in the Pivotal Tracker API, and getting it working required two scripts.
post-commit.bat – this is the standard batch file used by Subversion on Windows to run code after a successful commit. Subversion runs this automatically, and passes in two command-line arguments – the (local) path of the repository that accepted the commit, and the revision number created by that commit. Ours now looks like this:
@echo off
$ps = %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe
$ps Set-ExecutionPolicy unrestricted $ps -command "D:\svn\data\repositories\projects\hooks\post-commit.ps1" -repopath %1 -revision %2
A couple of things to notice. First, we’re running the powershell Set-ExecutionPolicy as part of the script. This is brute force and there’s probably a nicer way of doing it, but since the Powershell script runs as the user who owns the Subversion server process, and that user doesn’t have interactive logon rights, I couldn’t see a quicker way of getting that script to run reliably. Ah, Powershell security, how we love you.
Second – we’re passing the two command-line arguments into the powershell script as named parameters. Subversion will call the batch file as:
post-commit.bat D:\svn\data\repositories\projects 12345
and we’re translating that into
powershell.exe –command post-commit.ps1 –repopath D:\svn\data\repositories\projects –revision 12345
The bit that actually does the heavy lifting is post-commit.ps1
param([string]$repopath, [string]$revision)
$svnlook = "C:\Program Files\Subversion\bin\svnlook.exe"
$message = & "$svnlook" log $repopath -r $revision | Out-String
if ($message -match "#\d\d\d\d\d\d\d\d") {
$reponame = Split-Path $repopath –leaf
$author = & "$svnlook" author $repopath -r $revision | Out-String
# Grab a reference to System.Web so we can HtmlEncode things.
Add-Type -AssemblyName System.Web
$author = [System.Web.HttpUtility]::HtmlEncode($author)
$message = [System.Web.HttpUtility]::HtmlEncode($message)
# We run ViewCV on our Subversion server to browse code via the web. Tweak this to suit,
# or remove the <url></url> element from the XML completely.
$url = "http://subversion.mycompany.com/viewvc/$reponame`?view=revision&revision=$revision"
$headers = @{"X-TrackerToken" = "put your Pivotal Tracker API Token Here"}
# This is Powershell's "here-string" syntax for multiline string literals.
$body = @"<source_commit>
<message>$message</message>
<author>$author</author>
<commit_id>$revision</commit_id>
<url>$url</url>
</source_commit>
"@$r = Invoke-WebRequest -Uri http://www.pivotaltracker.com/services/v3/source_commits -ContentType "application/xml" -Method POST -Headers $headers -Body $body
Write-Host $r
} else {
# if nothing in the commit message matched the #12345678 syntax, then don’t bother calling the API.
}
To test it, first run the Powershell script directly from your command line. Say you’ve just committed revision 12345 to the “projects” repository, remembering to include [#12345678] in your commit comment where 12345678 is the PivotalTracker story ID.
PS D:\svn\data\repositories\projects\hooks> ./post-commit.ps1 –repopath D:\svn\data\repositories\projects –revision 12345
Your commit comment should appear in the story history within a few seconds.
Now check the batch file harness can run your Powershell properly – see the note below about revisions:
D:\svn\data\repositories\projects\hooks> post-commit.bat D:\svn\data\repositories\projects 12346
If that works, the whole kaboodle should work. A couple of caveats to watch out for:
-
If your post-commit hook fails, your Subversion client will give you something cryptic about “Commit failed: MERGE … 200 OK” – which is not particularly transparent. Best to get things working on the command line first before testing via Subversion itself.
-
I couldn’t get the same commit to produce multiple Pivotal tickets – when I was testing it, I had to create a fresh commit for each test run of the integration hook. This is possibly just Pivotal automatically de-duplicating identical stories – but worth knowing for test purposes