Jenkins Pipeline always fails - jenkins

My Jenkins pipeline stages are all successful yet the build always says it failed. To be clear, the build was a success and I would like it to register with Jenkins as successful but for some reason Jenkins thinks it has failed. All the stages say success in the dashboard yet the build is marked with a red ball and the console output ends with Finished: FAILURE.
Here is my pipeline file
node {
try{
stage 'Clone repo'
sh 'gcloud source repos clone <repo-name> --project=<project-name>'
dir('<repo-name>') {
try{
stage 'Run tests'
sh './gradlew test'
stage 'Run integration tests'
sh './gradlew integrationTest'
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: false,
reportDir: '<repo-name>/build/reports/integrationTest',
reportFiles: 'index.html',
reportName: 'Integration Test Reports'])
} finally {
stage 'Stop and remove docker containers'
sh 'docker-compose down'
sh 'docker-compose rm -f'
}
}
} finally {
deleteDir()
}
}

I realised I had included the full path to the html reports when I was actually inside a dir block. There was no indication in the logs of this.

is your problem solved ?
Anyway the deleteDir function can be a problem sometimes. Because deleteDir recursively deletes the current directory and its contents, you can raise an error if you try to delete the complete job workspace.
Take care to use it in a dir function as below:
dir('directoryToDelete') {
deleteDir()
}

Related

Jenkins pipeline script with invoking powershell script file is not working in stages and gets hanged till i abort

Hi am working on creating a descriptive pipeline which has 4 simple stages. Each stage steps is to invoke a powershell file with arguments.
pipeline{
agent none
stages{
stage("demo1"){
steps{
powershell returnStatus: true, script: ".\\file1.ps1 ${p1} ${p2} ${p3} ${p4} ${p5}"
}
}
stage("demo2"){
steps{
powershell returnStatus: true, script: ".\\file2.ps1 ${p1} ${p2} ${p3}"
}
}
stage("demo3"){
steps{
powershell returnStatus: true, script: ".\\file3.ps1 ${p1} ${p2} ${p3}"
}
}
stage("demo4"){
steps{
powershell returnStatus: true, script: ".\\file4.ps1 ${p1} ${p2} ${p3}"
}
}
}
}
The pipeline starts successfully and completes 1st stage and moves to second stage. Once the second stage steps is completed, it is not further moving to the third step. In console output i am seeing a refresh symbol and the job status says in progress. Until i abort the job the still loading.
Please help me in resolving the issue and what is the resolution for this.
Hey Guys thanks for all your support in making this issue resolved. As #mkemmerz and #DibakarAditya mentioned, all process has to be completed to proceed further. In my case winniumdriver process is still on, thats the reason jenkins is not moving to next stage. Added a command to kill the process. Working perfectly

How can I rename Jenkins' pull request builder's "status check" display name on GitHub

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!

No such DSL method 'publishHTML' found among steps

I have a jenkins DSL step that runs my python nosetests and creates a unittest coverage report.
Here is my jenkins stage.
stage ('Unit Tests') {
steps {
sh """
#. venv/bin/activate
export PATH=${VIRTUAL_ENV}/bin:${PATH}
make unittest || true
"""
}
post {
always {
junit keepLongStdio: true, testResults: 'report/nosetests.xml'
publishHTML target: [
reportDir: 'report/coverage',
reportFiles: 'index.html',
reportName: 'Coverage Report - Unit Test'
]
}
}
}
I get this error -
java.lang.NoSuchMethodError: No such DSL method 'publishHTML' found among steps.
How can I fix this error? I got this piece of code from a different repository.
The publishHTML method is provided by the HTLMPublisher Jenkins plugin. After installing the plugin on the primary Jenkins server, the publishHTML method will be available in the Jenkins Pipeline for both scripted and declarative syntax.

Jenkins Pipeline publish html report

Maven clean install generate new html file in following location
/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/DocsJmeterTests_20170601_151330/index.html
Here "DocsJmeterTests_20170601_151330" will change for every run. So i am trying to publish html report using publish html report plugin. Following is my Pipeline script
node {
build job: 'Docs_LoadTest'
stage('Results') {
publishHTML([allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir:
'/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/*/',
reportFiles: 'index.html',
reportName: 'Docs Loadtest Dashboard'
])
}
}
Getting following error while running the job
[htmlpublisher] Archiving HTML reports...
[htmlpublisher] Archiving at BUILD level
/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/* to
/var/lib/jenkins/jobs/Docs_Pipeline/builds/10/htmlreports/Docs_Loadtest_Dashboard
ERROR: Specified HTML directory '/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/*' does not exist.
Even we tried following options didnt worked
/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/**/
/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/DocsJmeterTests_*
/var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/DocsJmeterTests_*
_*
The HTML Publisher plugin does not seem to understand wildcards. What you could do in your Pipeline is using Linux's copy command, since that can work with wildcards.
This copies over the contents of all directories in the [Docs_LoadTest]/jmeter/reports folder to a jmeter_results folder in the local workspace:
sh 'cp -r /var/lib/jenkins/workspace/Docs_LoadTest/target/jmeter/reports/*/. target/jmeter_results/'
Note that you must clean both your target folder in the Docs_LoadTest folder and your Pipeline in between runs, else multiple reports will be copied over with this solution.
A better solution:
Would be to apply this trick in the Docs_LoadTest and use the Publish Artifact and Copy Artifact features. This works around having to hardcode the path to the other job and will work even if the Pipeline executes on another slave than the Docs_LoadTest. This does require the Copy Artifacts plugin.
Assuming Docs_LoadTest is a Freestyle job:
Add an Execute Shell Build step that copies the results to a fixed folder, e.g. jmeter_results:
mkdir -p target/jmeter_results/
cp -r target/jmeter/reports/*/. target/jmeter_results/
Then add an Archive Artifacts Post Build Archive Step with the following files to archive:
target/jmeter_results/*
In your Pipeline:
Use the Copy Artifact step to copy the files to target/jmeter_results folder in the local workspace:
step ([$class: 'CopyArtifact',
projectName: 'Docs_LoadTest',
filter: 'target/jmeter_results/*']);
Change the call to the HTML publisher to use this folder:
publishHTML([allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'target/jmeter_results',
reportFiles: 'index.html',
reportName: 'Docs Loadtest Dashboard'
])
I was having similar problem, only that I wanted to publish multiple reports.
What I ended up doing was I added simple groovy script to iterate through files in reports directory. You can use same/similar approach to get file name.
stage('publish reports') {
steps {
unstash 'source'
script {
sh 'ls target/jmeter/reports > listFiles.txt'
def files = readFile("listFiles.txt").split("\\r?\\n");
sh 'rm -f listFiles.txt'
for (i = 0; i < files.size(); i++) {
publishHTML target: [
allowMissing:false,
alwaysLinkToLastBuild: false,
keepAll:true,
reportDir: 'target/jmeter/reports/' + files[i],
reportFiles: 'index.html',
reportName: files[i]
]
}
}
}
}
Note: this example is used in declarative pipeline. Docs about readFile function.
I have tried simply the followings.
stage('Test-Junit') {
steps {
sh 'gradle test'
}
post {
always {
script {
def moduleNames = ["app", "core", ...]
for(i=0; i<moduleNames.size(); i++ ) {
publishHTML target: [
allowMissing:false,
alwaysLinkToLastBuild: false,
keepAll:true,
reportDir: moduleNames[i] + '/build/reports/tests/test',
reportFiles: 'index.html',
reportName: 'Test Report:' + moduleNames[i]
]
}
}
}
}
}
It will make all modules report and thus you can find them on left nav-bar of project dash-board.
It is not exactly the same scenario, but decided to publish my code because was really hard to understand, clarify and get documentation and accurate examples on how to publish different reports in just one final consolidated report, using the publishHTML plug-in for Jenkins.
A bit of background, we are executing different packages of testing, but some test cases can't run together because they could kill each other, so we need to execute, from the same code, in two different time frames due that we run test cases in parallel.
The solution was to execute by tags, so once the different execution using a Jenkins DSL - pipeline happens the builds produce just one report with different tabs on it.
So this is the final code that works for me:
pipeline {
agent any
stages {
stage('Git') {
steps {
git .....
}
}
stage('Exec-1') {
steps {
bat 'mvn -B clean verify -Dcucumber.filter.tags=#exec1 -Dserenity.outputDirectory=reports/site/serenity/exec1'
}
stage('Exec-2') {
steps {
bat 'mvn -B clean verify -Dcucumber.filter.tags=#exec2 -Dserenity.outputDirectory=reports/site/serenity/exec2'
}
}
stage('Exec-3') {
steps {
bat 'mvn -B clean verify -Dcucumber.filter.tags=#exec3 -Dserenity.outputDirectory=reports/site/serenity/exec3'
}
}
}
post {
always {
publishHTML target: [
reportName: 'Test',
reportDir: 'reports/site/serenity',
reportFiles: 'exec1/index.html, exec2/index.html, exec3/index.html',
reportTitles: 'Exec-1, Exec-2, Exec-3',
keepAll: true,
alwaysLinkToLastBuild: true,
allowMissing: false
]
}
}
}

How do I use the report plugin on (PMD, PHPCPD, checkstyle, Jdepend...) in a Jenkins pipeline?

I'm using Jenkins 2.x with a Jenkinsfile to run a pipeline.
I have built a job using Jenkinsfile and I want to invoke the Analysis Collector Plugin so I can view the report.
Here is my current Jenkinsfile:
#!groovy
node {
stage 'Build '
echo "My branch is: ${env.BRANCH_NAME}"
sh 'cd gitlist-PHP && ./gradlew clean build dist'
stage 'Report'
step([$class: 'JUnitResultArchiver', testResults: 'gitlist-PHP/build/logs/junit.xml'])
step([$class: 'hudson.plugins.checkstyle.CheckStylePublisher', checkstyle: 'gitlist-PHP/build/logs/phpcs.xml'])
step([$class: 'hudson.plugins.dry.DryPublisher', CopyPasteDetector: 'gitlist-PHP/build/logs/phpcpd.xml'])
stage 'mail'
mail body: 'project build successful',
from: 'siregarpandu#gmail.com',
replyTo: 'xxxx#yyyy.com',
subject: 'project build successful',
to: 'siregarpandu#gmail.com'
}
I want to invoke invoke Checkstyle, Junit and DRY plugin from Jenkins. How do I configure these plugins in the Jenkinsfile? Do these plugins support pipelines?
The following configuration works for me:
step([$class: 'CheckStylePublisher', pattern: 'target/scalastyle-result.xml, target/scala-2.11/scapegoat-report/scapegoat-scalastyle.xml'])
For junit configuration is even easier:
junit 'target/test-reports/*.xml'
step([$class: 'hudson.plugins.checkstyle.CheckStylePublisher', checkstyle: 'gitlist-PHP/build/logs/phpcs.xml'])
Also according to source code repo, the argument 'checkstyle' should be named 'pattern'.
Repo:
https://github.com/jenkinsci/checkstyle-plugin/blob/master/src/main/java/hudson/plugins/checkstyle/CheckStylePublisher.java#L42
This is how I handle this:
PMD
stage('PMD') {
steps {
sh 'vendor/bin/phpmd . xml build/phpmd.xml --reportfile build/logs/pmd.xml --exclude vendor/ || exit 0'
pmd canRunOnFailed: true, pattern: 'build/logs/pmd.xml'
}
}
PHPCPD
stage('Copy paste detection') {
steps {
sh 'vendor/bin/phpcpd --log-pmd build/logs/pmd-cpd.xml --exclude vendor . || exit 0'
dry canRunOnFailed: true, pattern: 'build/logs/pmd-cpd.xml'
}
}
Checkstyle
stage('Checkstyle') {
steps {
sh 'vendor/bin/phpcs --report=checkstyle --report-file=`pwd`/build/logs/checkstyle.xml --standard=PSR2 --extensions=php --ignore=autoload.php --ignore=vendor/ . || exit 0'
checkstyle pattern: 'build/logs/checkstyle.xml'
}
}
JDepend
stage('Software metrics') {
steps {
sh 'vendor/bin/pdepend --jdepend-xml=build/logs/jdepend.xml --jdepend-chart=build/pdepend/dependencies.svg --overview-pyramid=build/pdepend/overview-pyramid.svg --ignore=vendor .'
}
}
The full example you can find here: https://gist.github.com/Yuav/435f29cad03bf0006a85d31f2350f7b4
Reference links
https://jenkins.io/doc/pipeline/steps/
It appears that the plugins need to be modified to support working as Pipeline Steps, so if they have not been updated, they don't work.
Here is a list of compatible plugins that have been updated:
https://github.com/jenkinsci/pipeline-plugin/blob/master/COMPATIBILITY.md
And here is the documentation about how the plugins need to be updated to support Pipelines:
https://github.com/jenkinsci/pipeline-plugin/blob/master/DEVGUIDE.md

Resources