Jenkins job dsl and MSTest integration - jenkins

Jenkins Job DSL plugin is an extremely nice way to store CI config in repo and vary it from branch to branch.
The question is - is there a natural or close to natural way to run MSTest tests, parse results and display them.
Right now I do a powershell call, but that gives me only logs, not UI integration.
def testSomeProjectJob = job(testSomeProjectJobName) {
steps {
powerShell("& ${vstest} '${root}/SomeProject/SomeProject.Tests/bin/Debug/SomeProject.Tests.dll' ")
}
}
May be there is a publisher or a trick with templating, or some tips of writing a plugin to JOB DSL for that
UPD: final script template for MSTest and VSTest using #daspilker answer, jenkins xUnit Plugin and archiveXUnit
job('RunTests') {
steps {
// VSTEST
powerShell("& ${vstest} 'path/to/Tests.dll' /logger:trx ")
// Or MSBUILD
powerShell("& ${msbuild} /testcontainer:'path/to/Tests.dll' ")
}
publishers {
archiveXUnit {
msTest {
pattern('**/*.trx')
// deleteOutputFiles()
}
}
}
}

Using a PowerShell step is a good start. Install the xUnit Plugin to parse and display the results. It can parse all sorts of test results including MSTest. And you can use the DSL to configure the plugin.
Example:
job('example') {
steps {
powerShell('...')
}
publishers {
archiveXUnit {
msTest {
pattern('path/to/test/results')
}
}
}
}

Its for VSTest but I had to end up using the configure block to be able to use it in the DSL jobs.
static Closure useVsTest(List<String> dlls) {
return {
it / 'builders' << 'org.jenkinsci.plugins.vstest__runner.VsTestBuilder' {
vsTestName 'VS 14.0'
testFiles dlls.join('\n')
settings ''
testCaseFilter ''
enablecodecoverage false
useVsixExtensions true
platform 'x86'
otherPlatform ''
framework 'framework45'
otherFramework ''
logger 'trx'
otherLogger ''
cmdLineArgs '/TestAdapterPath:"."'
failBuild true
}
}
}

Related

matrix trigger mode in extendedEmail - Jenkins job DSL

I've a multi configuration project on Jenkins(ver. 2.222.1) We use JenkinsDSL(v1.77) to create the free-style jobs from the groovy scripts. Email notifications is with extendedEmail(v2.69)
It seems like trigger mode for notifications cannot be specified in the groovy script but it could be done via the UI as below(ONLY_PARENT or ONLY_CONFIGURATIONS or BOTH)
As I see here, below are the configurations we could specify for extendedEmail in groovy for DSL plugin
job('example') {
publishers {
extendedEmail {
recipientList('me#halfempty.org')
defaultSubject('Oops')
defaultContent('Something broken')
contentType('text/html')
triggers {
beforeBuild()
stillUnstable {
subject('Subject')
content('Body')
sendTo {
developers()
requester()
culprits()
}
}
}
}
}
}
It does not say anything in case of multi configuration project where I need the notifications to be sent only if parent job fails
I believe it exists on hipChatNotifier where we could specify as matrixTriggerMode
Is there a way to do this via extendedEmail publisher as we could do it on the UI?
Seems that this isn't supported by the Job DSL plugin, yet.
You can work around by using a custom configure block. For example
publishers {
extendedEmail {
...
}
}
configure { project -> project / 'publishers' / 'hudson.plugins.emailext.ExtendedEmailPublisher' << {
matrixTriggerMode('ONLY_PARENT')
}
}
Note the << to append a node to the publisher configuration instead of overwriting it.

Multiconfiguration / matrix build pipeline in Jenkins

What is modern best practice for multi-configuration builds (with Jenkins)?
I want to support multiple branches and multiple configurations.
For example for each version V1, V2 of the software I want builds targeting
platforms P1 and P2.
We have managed to set up multi-branch declarative pipelines. Each build has its own docker so its easy to support multiple platforms.
pipeline {
agent none
stages {
stage('Build, test and deploy for P1) {
agent {
dockerfile {
filename 'src/main/docker/Jenkins-P1.Dockerfile'
}
}
steps {
sh buildit...
}
}
stage('Build, test and deploy for P2) {
agent {
dockerfile {
filename 'src/main/docker/Jenkins-P2.Dockerfile'
}
}
steps {
sh buildit...
}
}
}
}
This gives one job covering multiple platforms but there is no separate red/blue status for each platform.
There is good argument that this does not matter as you should not release unless the build works for all platforms.
However, I would like a separate status indicator for each configuration. This suggests I should use a multi-configuration build which triggers a parameterised build for each configuration as below (and the linked question):
pipeline {
parameters {
choice(name: 'Platform',choices: ['P1', 'P2'], description: 'Target OS platform', )
}
agent {
filename someMagicToGetDockerfilePathFromPlatform()
}
stages {
stage('Build, test and deploy for P1) {
steps {
sh buildit...
}
}
}
}
There are several problems with this:
A declarative pipeline has more constraints over how it is scripted
Multi-configuration builds cannot trigger declarative pipelines (even with the parameterized triggers plugin I get "project is not buildable").
This also begs the question what use are parameters in declarative pipelines?
Is there a strategy that gives the best of both worlds i.e:
pipeline as code
separate status indicators
limited repetition?
This is a partial answer. I think others with better experience will be able to improve on it.
This is currently untested. I may be barking up the wrong tree.
Please comment or add a better answer.
Do not use pipeline parameters except where you need user input
Use a hybrid of a scripted and declarative pipeline
(see also https://stackoverflow.com/a/46675227/1569204)
Have a function which declares a pipeline based on parameters:
(see also https://jenkins.io/doc/book/pipeline/shared-libraries/)
Use nodes to create visible indicators in the pipeline (at least in blue ocean)
So something like the following:
def build(string platform) {
switch(platform) {
case P1:
dockerFile = 'foo'
indicator = 'build for foo'
break
case P2:
dockerFile = 'bar'
indicator = 'build for bar'
break
}
pipeline {
agent {
dockerfile {
filename "$dockerFile"
}
node {
label "$indicator"
}
}
stages {
steps {
echo "build it"
}
}
}
}
The relevant code could be moved to a shared library (even if you don't actually need to share it).
I think the cleanest approach is to have this all in a pipeline similar to the first one you presented, the only modification I would see here is making those parallel, so you would actually try and build/test for both platforms.
To reuse the previous stage's workspace you could do: reuseNode true
Something similar to this flow, that would have parallel build for platforms
pipeline {
agent 'docker'
stages {
stage('Common pre') { ... }
stage('Build all platforms') {
parallel {
stage('Build, test and deploy for P1') {
agent {
dockerfile {
filename 'src/main/docker/Jenkins-P1.Dockerfile'
reuseNode true
}
}
steps {
sh buildit...
}
}
stage('Build, test and deploy for P2') {
agent {
dockerfile {
filename 'src/main/docker/Jenkins-P2.Dockerfile'
reuseNode true
}
}
steps {
sh buildit...
}
}
}
}
stage('Common post parallel') { ... }
}
}

How Upload test results to alm by Jenkins groovy

I am using HP ALM v 5.2 and uploaded my test results by making free style project from the gui now I want to add this step to pipeline, I searched on the internet and found this guide but gives me this error no known implementation of interface jenkins.tasks.SimpleBuildStep is named TestResultToALMUploade with to many exceptions
this is sample of code
junit testResults: '**/target/*-reports/TEST-*.xml', allowEmptyResults: true
step ([$class: 'TestResultToALMUploader',
almServerName: 'HP ALM Server', //almServerName
credentialsId: 'ALM-CREDENTIALS',
almDomain: 'ALMDomain', // almDomain
almProject: 'AlmProject', //almProject,
testingFramework: 'JUnit', //testingFramework
testingTool: '', //testingTool
almTestFolder: 'TestHPALM', //almTestFolder
almTestSetFolder: 'TestHPALM', //almTestSetFolder
almTimeout: '-1', //almTimeout
testingResultFile: "**/junitResult.xml", //testingResultFile
jenkinsServerUrl: '' //jenkinsServerUrl
])
I am not sure, if you already found the answer, but I managed to do it with adding this fragment to "publishers" section:
job {
parameters { ... }
steps { ... }
... // some other job configuration here ...
publishers {
archiveJunit("junitReport.xml")
testResultToALMUploader {
almServerName('HP ALM Server')
credentialsId('ALM-CREDENTIALS')
almDomain('ALMDomain')
almProject('AlmProject')
testingFramework('JUnit')
testingTool('')
almTestFolder('TestHPALM')
almTestSetFolder('TestHPALM')
almTimeout("")
testingResultFile("**/junitResult.xml")
jenkinsServerUrl('')
}
}
}

How to add "single conditional steps" under build section using dsl script

I'm currently trying to develop a DSL script that can create a jenkins job with all required plugins and options.
I think I've almost completed all the section. But, I stuck up under build section where I've to include "conditional steps (single)" under Build.
Actually what I wanted is this
But, what I get is this
Here's the code that I used,
job('Sample_dev') {
steps {
conditionalSteps {
condition {
alwaysRun()
}
}
maven {
goals('install')
}
}
}
You have done few mistakes there:
Using multi-step DSL for achieving single step.
Pushed maven outside context like individual step.
Wrong DSL for Maven Step declaration.
Try following
job('Sample_dev')
{
steps{
singleConditionalBuilder{
condition{
alwaysRun()
}
buildStep {
maven{
targets('install')
name('')
pom('')
properties('')
jvmOptions('')
usePrivateRepository(false)
settings {
standard()
}
globalSettings {
standard()
}
injectBuildVariables(false)
}
}
runner {
fail()
}
}
}
}
The creator has deployed most on this url https://jenkinsci.github.io/job-dsl-plugin. But I would suggest you install in you local instance and access it via http://<your-jenkins-host>:<port> /plugin/job-dsl/api-viewer/index.html as Job DSL support auto generation so there is bright chance that plugin not listed above still has DSL support.

Conditional loops in Job DSL

I'm taking the build type i.e either Maven Job or Freestyle job as an input parameter (using the build parameterized plugin) and based on the input condition create the corresponding Job
My input parameter: "maven" (to create Maven job) , else block for freestyle Job.
if(params[build_type]=="maven"){
mavenJob('example') {
using(template_job)
scm {
svn {
location(svn_url)
}
}
}
}
freeStyleJob('example') {
using(template_job)
scm {
svn {
location(svn_url)
}
}
}
I'm facing the following error message and I'm very new to groovy so please excuse. Looking forward for any suggestions.Thanks.
Processing provided DSL script ERROR: (script, line 1) No such
property: params for class: script
The Job DSL script inherits the build parameters as variables in your Job DSL. So if you have a parameter named build_type, you can use it as a variable.
if (build_type == "maven") {
mavenJob('example') {
using(template_job)
scm {
svn {
location(svn_url)
}
}
}
}
See: User Power Moves: Parameterized Seed Job

Resources