I'm creating a post job on Jenkins pipeline to publish test results using junit, html and cobertura. The code looks like this
post {
always {
publishTestResults(
script: this,
junit: [
active:true,
allowEmptyResults:true,
archive: true,
pattern: '**/reports/mocha.xml',
updateResults: true
],
cobertura: [
active:true,
allowEmptyResults:true,
archive:true,
pattern: '**/coverage/cobertura/cobertura-coverage.xml'
],
html: [
active:true,
allowEmptyResults:true,
archive:true,
name: 'NYC/Mocha',
path: '**/coverage/html'
],
lcov: [
active:true,
allowEmptyResults:true,
archive:true,
name: 'LCOV Coverage',
path: '**/coverage/lcov/lcov-report'
]
)
cobertura coberturaReportFile: 'coverage/cobertura/cobertura-coverage.xml'
junit 'reports/mocha.xml'
cleanWs()
// deleteDir()
script {
FAILED_STAGE = env.STAGE_NAME
}
}
}
}
The problem is when I execute the job on Jenkins I receive an error message:
find . -wholename **/reports/mocha.xml -exec touch {} ;
touch: cannot touch './reports/mocha.xml': Permission denied
I suppose the issue raised by junit command. How could I solve this problem?
P/S: Jenkins server runs on Ubuntu. I tried to modify /etc/sudoers and add this line to make Jenkins executes command as root. It still could not solve my problem.
jenkins ALL=(ALL) NOPASSWD: ALL
From checking the code at: https://github.com/SAP/jenkins-library/blob/5c13a0e2a20132336824c70b743c364bcb5341f4/vars/testsPublishResults.groovy#L136
Looks like you can avoid the issue by setting updateResults to false
If you absolutely have to update the timestamp on the result file, you'll have to open a terminal session, go to the project workspace (with jenkins user) and try to run touch ./reports/mocha.xml and then debug it from there.
We have a project on GitHub which has two Jenkins Multibranch Pipeline jobs - one builds the project and the other runs tests. The only difference between these two pipelines is that they have different JenkinsFiles.
I have two problems that I suspect are related to one another:
In the GitHub status check section I only see one check with the following title:
continuous-integration/jenkins/pr-merge — This commit looks good,
which directs me to the test Jenkins pipeline. This means that our build pipeline is not being picked up by GitHub even though it is visible on Jenkins. I suspect this is because both the checks have the same name (i.e. continuous-integration/jenkins/pr-merge).
I have not been able to figure out how to rename the status check message for each Jenkins job (i.e. test and build). I've been through this similar question, but its solution wasn't applicable to us as Build Triggers aren't available in Multibranch Pipelines
If anyone knows how to change this message on a per-job basis for Jenkins Multibranch Pipelines that'd be super helpful. Thanks!
Edit (just some more info):
We've setup GitHub/Jenkins webhooks on the repository and builds do get started for both our build and test jobs, it's just that the status check/message doesn't get displayed on GitHub for both (only for test it seems).
Here is our JenkinsFile for for the build job:
#!/usr/bin/env groovy
properties([[$class: 'BuildConfigProjectProperty', name: '', namespace: '', resourceVersion: '', uid: ''], buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '5')), [$class: 'ScannerJobProperty', doNotScan: false]])
node {
stage('Initialize') {
echo 'Initializing...'
def node = tool name: 'node-lts', type: 'jenkins.plugins.nodejs.tools.NodeJSInstallation'
env.PATH = "${node}/bin:${env.PATH}"
}
stage('Checkout') {
echo 'Getting out source code...'
checkout scm
}
stage('Install Dependencies') {
echo 'Retrieving tooling versions...'
sh 'node --version'
sh 'npm --version'
sh 'yarn --version'
echo 'Installing node dependencies...'
sh 'yarn install'
}
stage('Build') {
echo 'Running build...'
sh 'npm run build'
}
stage('Build Image and Deploy') {
echo 'Building and deploying image across pods...'
echo "This is the build number: ${env.BUILD_NUMBER}"
// sh './build-openshift.sh'
}
stage('Upload to s3') {
if(env.BRANCH_NAME == "master"){
withAWS(region:'eu-west-1',credentials:'****') {
def identity=awsIdentity();
s3Upload(bucket:"****", workingDir:'build', includePathPattern:'**/*');
cfInvalidate(distribution:'EBAX8TMG6XHCK', paths:['/*']);
}
};
if(env.BRANCH_NAME == "PRODUCTION"){
withAWS(region:'eu-west-1',credentials:'****') {
def identity=awsIdentity();
s3Upload(bucket:"****", workingDir:'build', includePathPattern:'**/*');
cfInvalidate(distribution:'E6JRLLPORMHNH', paths:['/*']);
}
};
}
}
Try to use GitHubCommitStatusSetter (see this answer for declarative pipeline syntax). You're using a scripted pipeline syntax, so in your case it will be something like this (note: this is just prototype, and it definitely must be changed to match your project specific):
#!/usr/bin/env groovy
properties([[$class: 'BuildConfigProjectProperty', name: '', namespace: '', resourceVersion: '', uid: ''], buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '5')), [$class: 'ScannerJobProperty', doNotScan: false]])
node {
// ...
stage('Upload to s3') {
try {
setBuildStatus(context, "In progress...", "PENDING");
if(env.BRANCH_NAME == "master"){
withAWS(region:'eu-west-1',credentials:'****') {
def identity=awsIdentity();
s3Upload(bucket:"****", workingDir:'build', includePathPattern:'**/*');
cfInvalidate(distribution:'EBAX8TMG6XHCK', paths:['/*']);
}
};
// ...
} catch (Exception e) {
setBuildStatus(context, "Failure", "FAILURE");
}
setBuildStatus(context, "Success", "SUCCESS");
}
}
void setBuildStatus(context, message, state) {
step([
$class: "GitHubCommitStatusSetter",
contextSource: [$class: "ManuallyEnteredCommitContextSource", context: context],
reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/my-org/my-repo"],
errorHandlers: [[$class: "ChangingBuildStatusErrorHandler", result: "UNSTABLE"]],
statusResultSource: [ $class: "ConditionalStatusResultSource", results: [[$class: "AnyBuildResult", message: message, state: state]] ]
]);
}
Please check this and this links for more details.
You can use the Github Custom Notification Context SCM Behaviour plugin https://plugins.jenkins.io/github-scm-trait-notification-context/
After installing go to the job configuration. Under "Branch sources" -> "GitHub" -> "Behaviors" click "Add" and select "Custom Github Notification Context" from the dropdown menu. Then you can type your custom context name into the "Label" field.
This answer is pretty much like #biruk1230's answer. But if you don't want to downgrade your github plugin to work around the bug, then you could call the API directly.
void setBuildStatus(String message, String state)
{
env.COMMIT_JOB_NAME = "continuous-integration/jenkins/pr-merge/sanity-test"
withCredentials([string(credentialsId: 'github-token', variable: 'TOKEN')])
{
// 'set -x' for debugging. Don't worry the access token won't be actually logged
// Also, the sh command actually executed is not properly logged, it will be further escaped when written to the log
sh """
set -x
curl \"https://api.github.com/repos/thanhlelgg/brain-and-brawn/statuses/$GIT_COMMIT?access_token=$TOKEN\" \
-H \"Content-Type: application/json\" \
-X POST \
-d \"{\\\"description\\\": \\\"$message\\\", \\\"state\\\": \\\"$state\\\", \
\\\"context\\\": \\\"${env.COMMIT_JOB_NAME}\\\", \\\"target_url\\\": \\\"$BUILD_URL\\\"}\"
"""
}
}
The problem with both methods is that continuous-integration/jenkins/pr-merge will be displayed no matter what.
This will be helpful with #biruk1230's answer.
You can remove Jenkins' status check which named continuous-integration/jenkins/something and add custom status check with GitHubCommitStatusSetter. It could be similar effects with renaming context of status check.
Install Disable GitHub Multibranch Status plugin on Jenkins.
This can be applied by setting behavior option of Multibranch Pipeline Job on Jenkins.
Thanks for your question and other answers!
I am trying to execute a .vbs file by passing parameters in Jenkins pipeline script.
After clicking "Build with Parameters" I entered all input parameters but below script is not passing the values I entered.
The '${param.XXX}' seems to be not working. The values passed to vbs are always ${params.DELIVERY} ${params.SOURCE_ENV} ${params.TERGET_ENV} ${params.GENREPORT}
but ideally arguments passed to vbs should be equal to the data entered before triggering pipeline. Can anyone please help me?
#!/usr/bin/env groovy
pipeline {
agent any
parameters {
string(defaultValue: '', description: 'Delivery name', name: 'DELIVERY')
choice(choices:'DEV1\nDEV2\nDEV3',description: 'Select Source environment', name: 'SOURCE_ENV')
choice(choices:'TEST1\nTEST2\nTEST3',description: 'Select target environment', name: 'TERGET_ENV')
choice(choices:'Yes\nNo',description: 'Generate Report?', name: 'GENREPORT')
}
stages {
stage("Start Batch") {
steps {
bat '''
echo '${params.DELIVERY}'
echo '${params.SOURCE_ENV}'
echo '${params.TERGET_ENV}'
echo '${params.GENREPORT}'
cd "C:\\Users\\DELIVERY_BATCH\\src"
cscript.exe DELEXCEBATCH.vbs "C:\\Users\\Documents\\BatchFiles" ${params.DELIVERY} ${params.SOURCE_ENV} ${params.TERGET_ENV} ${params.GENREPORT}
EXIT /B 0
'''
}
}
stage("Create Summary Excel sheet") {
steps {
bat '''
echo 'Batch Execution is successful'
'''
}
}
}
}
This:
bat '''
Should be:
bat """
Because variables are only evaluated when double quotes are used.
I have one Jenkinsfile with two testing stages.
stage("test 1") {
dir("test 1") {
git url: "repo"
sh "${mvnHome}/bin/mvn -f pom.xml (...)"
git url: "repo"
sh "${mvnHome}/bin/mvn -f pom.xml (...)"
step([$class: 'Publisher', reportFilenamePattern: "${workspace}/(path)/testng-results-mod.xml"])
}
}
stage("test 2") {
dir("test_2") {
git url: "repo"
sh "${mvnHome}/bin/mvn -f pom.xml (...)"
git url: "repo"
sh "${mvnHome}/bin/mvn -f pom.xml (...)"
step([$class: 'Publisher', reportFilenamePattern: "${workspace}/(path)/testng-results-mod.xml"])
}
}
This is working fine. Both stages generates testng results file. But unfortunately i end up with just one xml result file, because first file is being overwriten by second test. Both test use same name.
There are two link in jenkins (build) to TestNG results, but they all lead to this same xml file. In build directory there is also just one file.
Is there any option to generate each test under different name? So they both will be avaliable in the end?
Ok. So after testing... it looks like you can have multiple xml files in output directory. TestNG pluging is displaying them as one report.
So Ive just added option to rename output file to _1.xml and _2.xml and it works.
My Jenkins pipeline definition looks like this (excerpt):
eslint: {stage('ES Lint') {
sh "bin/eslint ..."
step([$class: 'CheckStylePublisher', pattern:...])
}},
stylelint: {stage('Style Lint') {
sh "..."
sh "..."
step([$class: 'CheckStylePublisher', pattern: '...'])
step([$class: 'CheckStylePublisher', pattern: '...'])
}},
...
I have many steps that call the CheckStylePublisher. Unfortunately when displaying the output in the Jenkins UI, I see several CheckStylePublisher graphs, but they have no reference to the respective step.
Is there any way to name the CheckStylePublisher instances and link them to the stage name somehow? Thanks