Welcome!

XebiaLabs | Continuous Delivery and Agile DevOps Tools

XebiaLabs Blog

Subscribe to XebiaLabs Blog: eMailAlertsEmail Alerts
Get XebiaLabs Blog via: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Intel XML, XML Magazine

Blog Feed Post

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.

AllThreeWays

Software 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-manual

Before 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.

RestartMarker

On 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

 


XebiaLabs develops enterprise-scale Continuous Delivery and DevOps software, providing companies with the visibility, automation and control to deliver software faster and with less risk. Learn how…

The post Tracking the Dev/QA Cycle with XL Release appeared first on XebiaLabs.

Read the original blog entry...

More Stories By XebiaLabs Blog

XebiaLabs is the technology leader for automation software for DevOps and Continuous Delivery. It focuses on helping companies accelerate the delivery of new software in the most efficient manner. Its products are simple to use, quick to implement, and provide robust enterprise technology.