Before you start:
The Jenkins pipeline will perform the following steps:
To integrate the RTM API into your Jenkins pipelines, securely store the RTM_API_TOKEN as a credential in Jenkins. Follow these steps to add and configure the API token in Jenkins.
Here’s an example of a Jenkins pipeline script (Jenkinsfile) that integrates the import of JUnit test results into the RTM app.
pipeline {
agent any
environment {
RTM_API_TOKEN = credentials('rtm-api-token') // Credential ID for RTM API token
PROJECT_KEY = 'YOUR_PROJECT_KEY' // Replace with your RTM project key
RTM_URL = 'https://your-rtm-instance.com' // Replace with your RTM instance URL
}
stages {
stage('Checkout Code') {
steps {
checkout scm
}
}
stage('Build and Test') {
steps {
sh 'mvn clean test' // Adjust command based on your build tool
}
post {
always {
junit 'target/surefire-reports/*.xml' // Archive JUnit test results
}
}
}
stage('Archive Test Results') {
steps {
archiveArtifacts artifacts: 'target/surefire-reports/*.xml', fingerprint: true
}
}
stage('Import Test Results to RTM') {
steps {
script {
def testResultsZip = 'test-results.zip'
// Compress test result files into a ZIP
sh "zip -j ${testResultsZip} target/surefire-reports/*.xml"
// Prepare the API request
def importResponse = sh(
script: """
curl -X POST '${RTM_URL}/api/v2/automation/import-test-results' \\
-H 'Authorization: Bearer ${RTM_API_TOKEN}' \\
-F 'projectKey=${PROJECT_KEY}' \\
-F 'file=@${testResultsZip}' \\
-F 'reportType=JUNIT' \\
-F 'jobUrl=${env.BUILD_URL}'
""",
returnStdout: true
).trim()
echo "Import Response: ${importResponse}"
// Extract the task ID from the response if needed
// def taskId = parse the importResponse to get the task ID
}
}
}
}
post {
success {
echo 'Build and test execution succeeded.'
}
failure {
echo 'Build or test execution failed.'
}
}
}
See REST API for all available options to import endpoint.
If you want to monitor the status of the import task, you can extract the taskId from the response and make subsequent API calls to check the status. Add the following steps after importing test results to modify the pipeline:
stage('Check Import Status') {
steps {
script {
// Assuming importResponse contains the task ID
def taskId = importResponse // Parse the response to extract taskId
def statusResponse = sh(
script: """
curl -X GET '${RTM_URL}/api/v2/automation/import-status/${taskId}' \\
-H 'Authorization: Bearer ${RTM_API_TOKEN}'
""",
returnStdout: true
).trim()
echo "Import Status: ${statusResponse}"
// Optionally, parse statusResponse to determine if import is complete
}
}
}
Parse importResponse to extract the taskId, which depends on the format of the API’s response. Adjust the parsing logic accordingly.
Here’s how you might modify the import step to extract the taskId:
stage('Import Test Results to RTM') {
steps {
script {
def testResultsZip = 'test-results.zip'
// Compress test result files into a ZIP
sh "zip -j ${testResultsZip} target/surefire-reports/*.xml"
// Send the API request and capture the response
def importResponse = sh(
script: """
curl -X POST '${RTM_URL}/api/v2/automation/import-test-results' \\
-H 'Authorization: Bearer ${RTM_API_TOKEN}' \\
-F 'projectKey=${PROJECT_KEY}' \\
-F 'file=@${testResultsZip}' \\
-F 'reportType=JUNIT' \\
-F 'jobUrl=${env.BUILD_URL}' \\
--silent --show-error --fail
""",
returnStdout: true
).trim()
echo "Import Response: ${importResponse}"
// Assuming the response is a UUID string
def taskId = importResponse
// Wait for the import to complete (optional)
timeout(time: 5, unit: 'MINUTES') {
waitUntil {
def statusResponse = sh(
script: """
curl -X GET '${RTM_URL}/api/v2/automation/import-status/${taskId}' \\
-H 'Authorization: Bearer ${RTM_API_TOKEN}' \\
--silent --show-error --fail
""",
returnStdout: true
).trim()
echo "Import Status: ${statusResponse}"
// Parse the statusResponse to check if the import is complete
def status = readJSON text: statusResponse
return status.state == 'COMPLETED' || status.state == 'FAILED'
}
}
}
}
}
The above example uses the import API to return a plain UUID string and the status API to return a JSON object with a state field. Adjust parsing logic based on the actual API responses.