Your browser was unable to load all of the resources. They may have been blocked by your firewall, proxy or browser configuration.
Press Ctrl+F5 or Ctrl+Shift+R to have your browser try again.

Drop-down list for SVN tag select #1195

Zac ·
Greetings all,

Searching around the forum, I couldn't find anyone else having reported this, so I thought I'd post it in case anyone else finds it useful. We work from a Subversion repository, and one request we had was to be able to have a drop-down list of available SVN tags when a build is triggered. A bit of MVEL scripting later, and I've managed to make it happen. Each time a build is triggered, the Specify Build Options screen presents you with a list of choices. Getting this to work required a bit of configuration, but it seems to work well and has made our developers happy.

The scripts below assume a few things about variables that are configured:
[list]
svn_password - password to match. Note that the script will currently fail if any shell-significant characters are in the password.[/*:m]
buildInstance - One of "dev", "qa", "prod", etc. Script assumes 'trunk' should be disallowed for PROD builds.[/*:m][/list:u]
These scripts also assume you're using the standard SVN "trinity" layout of branches, tags, and trunk all in a single parent path.

You need a Subversion repository object. We'll assume it's called "SVN". The following attributes should be set:
[list]
Url to label as: https://example.org/svn/tags/{0}[/*:m]
[*]Plus username, password, and anything else you need of course.[/*:m][/list:u]
At a shared top-level configuration, define the following variables:

svn_tag_name: prompt as selection box. Set the choices script to the following:

${
repo = repositories.get("SVN");
if(repo instanceof com.pmease.quickbuild.plugin.scm.svn.SvnRepository) {
// It's SVN. Let's get a list of tags.
// Start with the label URL and trim off any tags/branches/trunk on the end.
sUrl = repo.getLabelUrl();
sUrl = sUrl.replaceAll("^(.*)/(?:branches/.*|tags/.*|trunk)/?$", "$1/tags/");

// Call SVN binary to get a list (one per line w/ a trailing slash)
sTags = util.readOutput(vars.get("svn_path") + "/svn" +
" --username " + vars.get("svn_username") +
" --password " + vars.get("svn_password") +
" list " + sUrl);

// Regex to cut off the trailing slashes.
pat = java.util.regex.Pattern.compile("^(.*)/$", java.util.regex.Pattern.MULTILINE);
mat = pat.matcher(sTags);
sTags = mat.replaceAll("$1");

if(vars.getValue("buildInstance").toLowerCase() != "prod") {
// Add a trunk option if we're not in prod.
sTags = "trunk\n" + sTags;
\}
return sTags;
\}
return "";
}


svn_tag: do not prompt. Set the value script to the following:

${
if(vars.get("svn_tag_name").isEmpty() || vars.getValue("svn_tag_name") == "trunk") {
return "trunk";
\} else {
return "tags/" + vars.get("svn_tag");
\}
}


Assuming you have sub-configurations for dev, qa, prod, etc., you might wish to override the 'svn_tag_name' variable in the dev configuration and set it to 'trunk'. That way dev will always build the latest without prompting.

Best regards,
Zac Bedell
  • replies 3
  • views 3024
  • stars 0
robinshen ADMIN ·
Hi Zac,

This is cool. Thanks for sharing!
Zac ·
Just wanted to update this a bit as our requirements have evolved. As we've ended up with more branches of products floating around, the need arose to be able to do HEAD-of-branch builds in addition to HEAD-of-trunk and tag-based. Minor change to the above scripts made it work:

svn_tag_name:

${
repo = repositories.get("StarTeam"); // <- Note this is historical crud. We hard-coded the repo name in a bunch of places, and we're stuck with 'StarTeam' (in name only...) instead of SVN.
if(repo instanceof com.pmease.quickbuild.plugin.scm.svn.SvnRepository) {
// It's SVN. Let's get a list of tags.
// Start with the label URL and trim off any tags/branches/trunk on the end.
sUrl = repo.getLabelUrl();
sUrl = sUrl.replaceAll("^(.*)/(?:branches/.*|tags/.*|trunk)/?$", "$1/tags/");

// Call SVN binary to get a list (one per line w/ a trailing slash)
sTags = util.readOutput(vars.get("svn_path") + "/svn" +
" --no-auth-cache --non-interactive " +
" --username " + vars.get("svn_username") +
" --password " + vars.get("svn_password") +
" list " + sUrl);

// Regex to cut off the trailing slashes.
pat = java.util.regex.Pattern.compile("^(.*)/$", java.util.regex.Pattern.MULTILINE);
mat = pat.matcher(sTags);
sTags = mat.replaceAll("tags/$1");

// Now get the branches
sUrl = repo.getLabelUrl();
sUrl = sUrl.replaceAll("^(.*)/(?:branches/.*|tags/.*|trunk)/?$", "$1/branches/");

// Call SVN binary to get a list (one per line w/ a trailing slash)
sTagsB = util.readOutput(vars.get("svn_path") + "/svn" +
" --no-auth-cache --non-interactive " +
" --username " + vars.get("svn_username") +
" --password " + vars.get("svn_password") +
" list " + sUrl);

// Regex to cut off the trailing slashes.
mat = pat.matcher(sTagsB);
sTagsB = mat.replaceAll("branches/$1");

sTags = sTagsB + "\n" + sTags;

if(vars.getValue("buildInstance").toLowerCase() != "prod") {
// Add a trunk option if we're not in prod.
sTags = "trunk\n" + sTags;
\}
return sTags;
\}
return "";
}


And svn_tag:

${
if(vars.get("svn_tag_name").isEmpty() || vars.getValue("svn_tag_name") == "trunk") {
return "trunk";
\} else {
return vars.get("svn_tag_name");
\}
}


This lets branches list above tags in the drop-down. We use a Remember=yes variable for these, so if we're going to be running QA builds off a particular branch for a while, someone just needs to go in manually once to pick the branch, then all nightly or otherwise scheduled builds will keep building HEAD of that branch until somebody changes it. I'm debating adding a check to not include branches for production builds (so forcing a tag for releases), but so far I haven't implemented that. Easy enough to mirror the check for adding 'trunk' the same for branches if need be.


I've said this before elsewhere, but thanks yet a again for making QuickBuild such a well-designed framework for controlling build automation. Little scripts like this are so easy to put together, and them seem like "magic" to the folks in my office that I'm supporting with QuickBuild. It's so nice to be able to reply, "Sure, that'll be easy!" for so many requests and be able to knock out stuff like this in an hour or so. Such a time saver!

Thanks again,
Zac
robinshen ADMIN ·
Hi Zac,

Perhaps the chained selection list (introduced in recent QA release) can be used to make the job more easier. You may configure two selection boxes, one to select branch, and another to select tags in that branch. Once branch is selected, another selection box can be configured to populate tags in that branch automatically for further selection. Refer to below link on more details of chained build option:
http://wiki.pmease.com/display/QB31/Cha ... ld+Options

Regards
Robin