Skip to main content
DevOps icon showing cogs

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

DevOps

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/restartMarker.py" />
 <property name="restartTaskId" category="output" />
</type>
We also provide this short script in demo/restartMarker.py 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.
#!/bin/sh
python /usr/local/demo/gitUtilities/parseCommitAndCallXLR.py `git log -1 HEAD | tail -1 | awk '{print $1}'`
And a Python script handles the plumbing:
import re
import requests
import sys
HTTP_SUCCESSFUL = 200
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 = requests.post(newReleaseUrl, data=payload, headers=headers)
 if r1.status_code != HTTP_SUCCESSFUL:
  sys.exit(1)
 print r1.json()['id']
 startReleaseUrl = "http://admin:xlradmin@localhost:5516/releases/%s/start" % r1.json()['id']
 r2 = requests.post(startReleaseUrl)
 if r2.status_code != HTTP_SUCCESSFUL:
  sys.exit(1)
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
 payload='[{"key":"${restartPhaseId}","value":"Test","password":null,"type":"SCRIPT_RESULT"},{"key":"${restartReleaseId}","value":"Test","password":null,"type":"SCRIPT_RESULT"},{"key":"${restartTaskId}","value":"Test","password":null,"type":"SCRIPT_RESULT"}]'
 headers = {'Content-Type': 'application/json'}
 r3 = requests.post(restartPhaseUrl)
 if r3.status_code != HTTP_SUCCESSFUL:
  sys.exit(1)
 r4 = requests.post(resumeReleaseUrl, data=payload, headers=headers)
 if r4.status_code != HTTP_SUCCESSFUL:
  sys.exit(1)
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:
 createNewReleaseAndStart() 
else:
 restartReleaseAndResume(m)
  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
Ascension Launch Banner
Apr 26, 2022

Get ready for peak performance with Digital.ai’s newest AI-Powered DevOps Platform Ascension Release

DevOps
Today, Digital.ai is excited to announce our latest AI-Powered DevOps ...
Read More
Jan 24, 2022

Digital.ai Value Stream Delivery for SAFe®: The key to amazing business outcomes

DevOps
The Scaled Agile Framework (SAFe) is the world’s leading framework for ...
Read More
Dec 09, 2021

How SaaS and cloud-based solutions helped the U.S. Department of Veterans Affairs achieve digital transformation

DevOps
Modernizing legacy systems was an ongoing goal for the U.S. Department ...
Read More
Nov 29, 2021

Increase velocity and reduce risk with AI and machine learning

DevOps
Artificial Intelligence (AI) and machine learning (ML) have proven use ...
Read More
Contact Us