How to execute the garbage collector in a Jenkinsfile pipeline? - jenkins

I have a Jenkinsfile:
pipeline {
agent any
stages {
stage('Install dependencies') {
steps {
sh 'yarn'
}
}
}
}
How can I execute the Java garbage collector in the pipeline script?
This related question and answer hints at the monitoring plugin but you still have to manually click with it.

Run the garbage collector in a pipeline script:
pipeline {
agent any
stages {
stage('Run garbage collector') {
steps {
script {
System.gc();
}
}
}
stage('Install dependencies') {
steps {
sh 'yarn'
}
}
}
}
On first execution, this job will fail. In the console output you will find an error:
Scripts not permitted to use staticMethod java.lang.System gc. Administrators can decide whether to approve or reject this signature.
You can approve the script signature here: https://jenkins.YOUR_URL.com/scriptApproval/
allow java.lang.System gc
Solved when I found this issue.

Related

How to make build timeout in jenkins pipeline groovy script?

I saw declarative timeout example, e.g.
options{
timeout(100)
}
but it cannot work in my groovy file for jenkins pipeline. Also, I cannot find more documentation about this API on jenkins site.
You can put the timeout inside the stage.
stage ("deploy") {
steps {
script {
try {
timeout(time: 180, unit: 'SECONDS') {
sh("RUN COMMAND")
}
}
catch (err) {
echo "Timeout."
}
}
}
}
If you don't use try/catch, a timeout would cause a failure of this build, then your build will be interrupted on this stage.

How to kill a stage of Jenkins Pipeline?

I've a Jenkins pipeline with multiple stages but because of some issue, in one of the stages, it is likely to run longer unnecessarily.
Instead of aborting entire pipeline build and skip next stages, I want to kill that specific stage on which other stages are not dependent.
Is there a way to kill specific stage of Jenkins pipeline?
There are ways to skip a stage. But I'm not sure if there are options to kill a long running stage. I'd simply add a conditional expression to run the stage or not OR maybe you could put a timeout condition wrapped in a try..catch block for the long running unnecessary stage to skip and proceed to other stages you want like as below.
pipeline {
agent any
stages {
stage('stage1') {
steps {
script {
try {
timeout(time: 2, unit: 'NANOSECONDS')
echo "do your stuff"
} catch (Exception e) {
echo "Ended the never ending stage and proceeding to the next stage"
}
}
}
}
stage('stage2') {
steps {
script {
echo "Hi Stage2"
}
}
}
}
}
OR Check this page for conditional step/stage.
You can try using "try/catch" block in the scripted pipeline. Even if there is error in a particular stage, Jenkins will continue to execute the next stage.
node {
stage('Example') {
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed, I should sound the klaxons!'
throw
}
}
}
You can refer documentation here: https://jenkins.io/doc/book/pipeline/syntax/

How to run Jenkins scripted pipeline job on free slave?

I want to run Jenkins scripted pipeline job at the specified slave at the moment when no other job is running on it.
After my job will be started, no other jobs should be performed on this slave, they will have to wait for my job ending running
All the tutorials that I found allowed me to run job on the node when it is free but did not protect me from launching other jobs on this node
Could you tell me how can I do this?
Because Pipeline has two Syntax, there are two ways to achieve that. For scripted pipeline please check the second one.
Declarative
pipeline {
agent none
stages {
stage('Build') {
agent { label 'slave-node​' }
steps {
echo 'Building..'
sh '''
'''
}
}
}
post {
success {
echo 'This will run only if successful'
}
}
}
Scripted
node('your-node') {
try {
stage 'Build'
node('build-run-on-this-node') {
sh ""
}
} catch(Exception e) {
throw e
}
}

Limiting Jenkins pipeline to running only on specific nodes

I'm building jobs that will be using Jenkins piplines extensively. Our nodes are designated per project by their tags, but unlike regular jobs the pipeline build does not seem to have the "Restrict where this project can be run" checkbox. How can I specify on which node the pipeline will run the way I do for regular jobs?
You specify the desired node or tag when you do the node step:
node('specialSlave') {
// Will run on the slave with name or tag specialSlave
}
See https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#node-allocate-node for an extended explanation of the arguments to node.
Edit 2019: This answer (and question) was made back in 2017, back then there only was one flavor of Jenkins pipeline, scripted pipeline, since then declarative pipeline has been added. So above answer is true for scripted pipeline, for answers regarding declarative pipeline please see other answers below.
Choosing a node which has the label X in a declarative pipeline with json format:
pipeline {
agent { label 'X' }
...
...
}
You also can apply multiple labels with or (||) or with and (&&) operator.
Running the job on any of the nodes which has label X or label Y:
agent { label 'X || Y' }
Running the job only on nodes which have both label:
agent { label 'X && Y' }
More in the Jenkins Pipeline reference guide.
ps: if you are reading this you probably have just started using Jenkins pipeline and you are not sure if you should use declarative or scripted pipeline. Short answer: it's better to start with declarative. From jenkins.io:
Declarative and Scripted Pipelines are constructed fundamentally
differently. Declarative Pipeline is a more recent feature of Jenkins
Pipeline which:
provides richer syntactical features over Scripted Pipeline syntax, and
is designed to make writing and reading Pipeline code easier.
To be clear, because Pipeline has two Syntax, there are two ways to achieve that.
Declarative
pipeline {
agent none
stages {
stage('Build') {
agent { label 'slave-node​' }
steps {
echo 'Building..'
sh '''
'''
}
}
}
post {
success {
echo 'This will run only if successful'
}
}
}
Scripted
node('your-node') {
try {
stage 'Build'
node('build-run-on-this-node') {
sh ""
}
} catch(Exception e) {
throw e
}
}
Agent or Node where we should not execute the jenkins job :
This is the negation of the problem statment i.e. node where not to run
It was most weird solution to me but issue has been already raised to jenkins community
agent { label '!build-agent-name' }
If you need to run entire jenkins pipeline to run on single node, use the following format
pipeline {
agent {
label 'test1'
}
stages {
stage('Build') {
steps {
echo 'Building..'
}
}
stage('Test') {
steps {
echo 'Testing..'
}
}
stage('Deploy') {
steps {
echo 'Deploying....'
}
}
}
}
if you need to execute each stage in different nodes, use the below format,
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building..'
}
}
stage('Test') {
steps {
node("test1"){
echo 'Testing..'
}
}
}
stage('Deploy') {
steps {
echo 'Deploying....'
}
}
}
}

Scripted Jenkins pipeline: continue on fail

Is there a way to continue execution of the scripted pipeline even if the previous stage failed? I need to run specific commands (cleanup) when the build fails before the whole job fails.
The accepted answer wouldn't fail the stage or even mark it as unstable. It is now possible to fail a stage, continue the execution of the pipeline and choose the result of the build:
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "exit 1"
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}
In the example above, all stages will execute, the pipeline will be successful, but stage 2 will show as failed:
As you might have guessed, you can freely choose the buildResult and stageResult, in case you want it to be unstable or anything else. You can even fail the build and continue the execution of the pipeline.
Just make sure your Jenkins is up to date, since this is a fairly new feature.
The usual approach is to wrap your steps within a try block.
try {
sh "..."
} catch (err) {
echo "something failed"
}
// cleanup
sh "rm -rf *"
To ease the pain and make the pipeline code more readable, I've encapsulated this in another method here in my global library code.
Another approach, esp. created because of this very issue, are the declarative pipelines (blog, presentation).
post {
always {
cleanWs()
}
}
}
Will always cleanup the job even if the rest fails

Resources