Skip to main content
DevOps Image

This post is from the XebiaLabs blog and has not been updated since the original publish date.

Last Updated Dec 13, 2015 — DevOps Expert

Tracking the Dev/QA Cycle with XL Release


Let's take some inspiration from this diagram from Gene Kim, author of The Phoenix Project, and consider how DevOps tooling can help you automate "The Third Way": the continual experimentation and learning cycle.

AllThreeWaysSoftware development has shifted to a new paradigm:  we build/deploy/test in short cycles.  Our Third Way is one of continuous feedback and improvement, which improves productivity at a small and totally justifiable cost of managing all those cycles. How many cycles have we run? Where are we in the current cycle? How many more do we need to run? XL Release can help in this challenge. Let's consider a two-phase XL Release template that manages the Dev-QA cycle for the Acme Anvil Company. In the Development phase, some one-time initialization tasks are followed by development and build tasks, then a gate to mark the phase for approval. The QA phase is a simple provision/deploy/test.XLR-template-manualBefore we introduce automation, here is how we run the cycle manually: we proceed through the development tasks and into QA, and whenever the Test task fail, we restart at the Development task. This represents the iterative development process, and we repeat it until we can test successfully. With XL Release managing and tracking the cycle, this is accomplished by pressing the Restart Phase button in the GUI, and then choosing the phase and task at which we want to pick up again. Now let's perform some enhancements to promote automation: First, we'll insert a restart marker -- a simple python script that stores its own task id into a release variable. This will be our restart point; the variable will be used in a REST API call later.XLR-template-auto  Some coding comes into play here.  The Restart Marker is not an out-of-the-box type, but it's easy to extend the built-in xlrelease.PythonScript by adding this code to XL Release's synthetic.xml file:
<type type="demo.RestartMarker" extends="xlrelease.PythonScript">
 <property name="scriptLocation" default="demo/" />
 <property name="restartTaskId" category="output" />
We also provide this short script in demo/ so the task saves its own task id:
restartTaskId = '-'.join(getCurrentTask().id.split('/')[1:])
And we provide a variable denoted by the ${...} notation when we place this task in the release template, so our task id is accessible to any subsequent task within this release.RestartMarkerOn the QA side, we replace the manual test task with an automated test; on failure it sets another release variable which conditionally runs or skips the subsequent task to create a Jira issue.  The task id for our restart will appear in the Jira comment:CreateJiraIssue  JiraSED99  The developer who addresses the failure will include this task id in the commit message when committing to Git:
git commit -am "Release1234567-Phase1234567-Task1234567 Commit message here"
Finally, to close the loop, a post-commit Git hook invokes a short Python script to parse the commit message and take the appropriate action:  either begin a new release or restart another cycle if a task id is present.
python /usr/local/demo/gitUtilities/ `git log -1 HEAD | tail -1 | awk '{print $1}'`
And a Python script handles the plumbing:
import re
import requests
import sys
def createNewReleaseAndStart():
 print "No phase id found in commit message"
 print "Invoke new release from template here"
 newReleaseUrl = "http://admin:xlradmin@localhost:5516/releases"
 payload = '{"title":"Test-Post-Call-6","description":null,"owner":{"username":"admin","fullName":"XL Release Administrator"},"scheduledStartDate":"2015-12-10T14:00:00.000Z","dueDate":"2015-12-10T22:00:00.000Z","plannedDuration":null,"variables":[{"key":"${restartTaskId}","value":"","password":null,"type":"DEFAULT"}, {"key":"${testResult}","value":"","password":null,"type":"DEFAULT"}],"tags":["ACME"],"flag":{"status":"OK"},"abortOnFailure":false,"scriptUsername":"admin","scriptUserPassword":"xlradmin","templateId":"Release2338668"}'
 headers = {'Content-Type': 'application/json'}
 r1 =, data=payload, headers=headers)
 if r1.status_code != HTTP_SUCCESSFUL:
 print r1.json()['id']
 startReleaseUrl = "http://admin:xlradmin@localhost:5516/releases/%s/start" % r1.json()['id']
 r2 =
 if r2.status_code != HTTP_SUCCESSFUL:
def restartReleaseAndResume(m):
 taskId = m.string[:m.end()] 
 phaseId = '-'.join(taskId.split('-')[:-1])
 releaseId = '-'.join(phaseId.split('-')[:-1])
 print "Restarting XL Release Phase:\nReleaseId is %s\nPhaseId is %s\nTaskId is %s\n" % (releaseId, phaseId, taskId)
 restartPhaseUrl = "http://admin:xlradmin@localhost:5516/releases/%s/restartPhases?fromPhaseId=%s&fromTaskId=%s" % (releaseId, phaseId, taskId)
 resumeReleaseUrl = "http://admin:xlradmin@localhost:5516/releases/%s/resume" % releaseId
 headers = {'Content-Type': 'application/json'}
 r3 =
 if r3.status_code != HTTP_SUCCESSFUL:
 r4 =, data=payload, headers=headers)
 if r4.status_code != HTTP_SUCCESSFUL:
argument = sys.argv[1]
print "Argument is %s\n" % argument
taskMatch = re.compile('^Release[0-9]+-Phase[0-9]+-Task[0-9]+')
m = taskMatch.match(argument)
if m is None:
  And now we arrive at the bottom line:  when XL Release tracks the Dev/QA cycle in this way, it furnishes statistics like this, giving how many iterations and their durations:BetterReleaseValueStream 
Have you seen the new XL Release Doc's site? Videos, How to's and much more all in one convenient location. Check it out...

More from the Blog

View more
Sep 13, 2021

The Expedited Journey of Digital Transformation

Alan Brown, Digital Transformation Advisor at conducts a se ...
Read More
Aug 23, 2021

Is Data Analytics Missing From Your Digital Transformation?

Nearly every major enterprise is already in the process of digital tra ...
Read More
Aug 19, 2021

Creative Ways to Automate Developer Workflows

When an organization begins an Agile or DevOps journey, the process ca ...
Read More
Aug 12, 2021

How Automation Enhances Efficiency and Delivery Speed In a DevOps Environment

When organizations make the decision to move to a DevOps environment, ...
Read More
Contact Us