Skip to main content

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

Last Updated Mar 23, 2015 — DevOps Expert

A Tale of Two Build Tools: Integrating XL Release with Jenkins and Bamboo

DevOps

I discovered that XL Release does not have built-in support to integrate with the Bamboo build tool as it does for Jenkins. But I also discovered that XL Release's extensibility makes it easy to configure a type definition and a script to enable an interface with Bamboo.

Let's look at the support for Jenkins. XL Release provides a task definition:xlr-jenkins-taskand an entry under the configuration tab:xlr-jenkins-serverWith these we can define one or more Jenkins servers and use them to execute the build jobs defined on them. Nice. Bamboo doesn't have such out-of-the-box support, so let's take a look at how we could configure the objects we need.  Since Bamboo has a REST API, we can extend the HttpConnection object to provide us a Bamboo Server object by defining a type in xl-release-server/ext/synthetic.xml:
<type type="bamboo.Server" extends="configuration.HttpConnection" />
Now we need a task to call out to the API; let's extend the PythonScript object for this so we can take advantage of Python tremendous versatility. The script will actually run under Jython, so we can utilize Java classes too if needed. Our input will be the project-plan key to identify the Bamboo plan, and let's code a few output fields to return some information about the build after it completes.
<type type="bamboo.RunPlan" extends="xlrelease.PythonScript">
 <property name="bambooServer" category="input" label="Server" referenced-type="bamboo.Server" kind="ci" />
 <property name="projPlanKey" category="input" />
 <property name="buildNumber" category="output" />
 <property name="buildState" category="output" />
 <property name="state" category="output" />
</type>
Our next task is to write the Python script to call out to Bamboo. The namespace of the type, "bamboo" in this case, determines the script directory, and the type name determines the script name. So our script will be called RunPlan.py and will live in xl-release-server/ext/bamboo. The script starts with some typical Python imports. We'll use com.xhaus.jyson.JysonCodec for json since that's included in the XL Release libraries. Next we set some variables for contentType and headers for all of our HTTP calls, and define some boolean and text fields from the build result. Finally the main body of the code make a post request to Bamboo's url using the built-in HttpRequest object. We supply the url, content type and headers. We could have added authentication here to override what's defined on the Bamboo Server object, but let's leave that for later. An empty set of curly braces is required for the JSON content body. Then we use the JSON library module to parse two items out of the results: the build number and the build result key. We store the latter in the variable brkey to keep it handy to pass to our helper methods. A simple while loop polls for a finished result every five seconds. That interval would be better as a configurable value; this is something else we'll save for later. When the loop ends, we query the job's results (note the change in the query string from "queue" to "result"), print some messages and set the two state output variables so XL Release can use them to control future actions.  See the xlr-bamboo-plugin repo for future updates to the code.
import sys
import time
import com.xhaus.jyson.JysonCodec as json
print "Executing RunPlan.py\n"
if bambooServer is None:
 print "No server provided."
 sys.exit(1)
contentType = 'application/json'
headers = {'accept' : 'application/json'}
def finished(brkey):
 request = HttpRequest(bambooServer)
 response = request.get('/rest/api/latest/result/' + brkey, contentType=contentType, headers=headers)
 return json.loads(response.response)['finished']
def successful(brkey):
 request = HttpRequest(bambooServer)
 response = request.get('/rest/api/latest/result/' + brkey, contentType=contentType, headers=headers)
 return json.loads(response.response)['successful']
def getState(brkey):
 request = HttpRequest(bambooServer)
 response = request.get('/rest/api/latest/result/' + brkey, contentType=contentType, headers=headers)
 return json.loads(response.response)['state']
def getBuildState(brkey):
 request = HttpRequest(bambooServer)
 response = request.get('/rest/api/latest/result/' + brkey, contentType=contentType, headers=headers)
 return json.loads(response.response)['buildState']
def getPrettyBuildStartedTime(brkey):
 request = HttpRequest(bambooServer)
 response = request.get('/rest/api/latest/result/' + brkey, contentType=contentType, headers=headers)
 return json.loads(response.response)['prettyBuildStartedTime']
def getPrettyBuildCompletedTime(brkey):
 request = HttpRequest(bambooServer)
 response = request.get('/rest/api/latest/result/' + brkey, contentType=contentType, headers=headers)
 return json.loads(response.response)['prettyBuildCompletedTime']
request = HttpRequest(bambooServer)
response = request.post('/rest/api/latest/queue/' + projPlanKey, '{}', contentType=contentType, headers=headers)
result = json.loads(response.response)
buildNumber = result['buildNumber']
print 'Build number is ' + str(buildNumber) + '\n'
brkey = result['buildResultKey']
while (not finished(brkey)):
 time.sleep(5)
print "Build job started at " + getPrettyBuildStartedTime(brkey) + "\n"
prettyBuildCompletedTime = getPrettyBuildCompletedTime(brkey)
if successful(brkey):
 print "Build job completed successfully at " + prettyBuildCompletedTime + "\n"
else:
 print "Build job failed at " + prettyBuildCompletedTime + "\n"
buildState = getBuildState(brkey)
state = getState(brkey)

More from the Blog

View more
Feb 22, 2021

Reckoning DevOps’ role in the enterprise value stream

DevOps
If you’re a software or digital solutions company, you may use DevOps ...
Read More
Feb 10, 2021

Customer spotlight: Schneider avoiding bumps in the road with DevOps adoption

DevOps
Everyone wants to deliver software faster and more reliably. Companies ...
Read More
Jan 06, 2021

How testing automation can build a culture of QA while accelerating continuous delivery

DevOps
An organization’s level of automated test coverage is quickly emerging ...
Read More
Jul 30, 2020

Part 2: Is Technology Slowing Down Your Digital Transformation?

DevOps
In part one of this post, we shared insights from Andreas Prins’ webin ...
Read More
Contact Us