Prevent Jenkins job from building from another jenkins file - jenkins

We have 2 jenkins job AA and BB.
Is there a way to allow BB only to be trigger from AA after it completes?

Basically, you can use build triggers to do this. More about build triggers can be found here. There are two ways to add build triggers. Following is how you can add triggers using the UI. By going to Configure Job you can add triggers. Please refer to the following image.
In a declarative pipeline, you can add triggers as shown below.
pipeline {
agent any
triggers { upstream(upstreamProjects: 'AA', threshold: hudson.model.Result.SUCCESS) }
stages {
stage('Hello') {
steps {
echo 'Hello World BB'
}
}
}
}
Here you can specify the threshold on when to trigger the build based on the status of the upstream build. There are 4 different thresholds.
hudson.model.Result.ABORTED: The upstream build was manually aborted.
hudson.model.Result.FAILURE: The upstream build had a fatal error.
hudson.model.Result.SUCCESS: The upstream build had no errors.
hudson.model.Result.UNSTABLE: The upstream build had an unstable result.
Update 02
If you want to restrict all other jobs/users from triggering this job you will have to restructure your Job. You can wrap your stages with a parent Stage and conditionally check who triggered the Job. But note that the Job will anyway trigger but the stages will be skipped. Please refer the following pipeline.
pipeline {
agent any
triggers { upstream(upstreamProjects: 'AA', threshold: hudson.model.Result.SUCCESS) }
stages{
stage('Parent') {
// We will restrict triggering this Job for everyone other than Job AA
when { expression {
print("Checking if the Trigger is allowed to execute this job")
print('AA' in currentBuild.buildCauses.upstreamProject)
}
}
stages {
stage('Hello') {
steps {
echo 'Hello World BB'
}
}
}
}
}
}

Related

How to return to inital agent of a Jenkinx matrix after a stage executed on another agent?

Is it possible in a Matrix-cell of a Jenkins declarative pipeline to execute a later stage on the pipeline's 'initial/main' agent, after a previous stage of the same cell has been executed on another agent (identified by label)?
To put this into context, I want to build native-binaries for different platforms in a Jenkins declarative pipeline using a matrix stage where each cell is responsible to
collect the native's sources for that platform
build the native-binaries from the sources for that platform
collect the just build native-binaries and distribute them to the platform specific artefacts
Step two has to be performed on special agents, which are prepared to build the binaries for a particular platform and are identified by their label. Step one and three has to be performed on the initial agent, the pipeline's 'main' agent where the sources are checkout from SCM. In the end the native-binaries are bundled together and distributed from the pipeline's inital/main agent. To transfer of sources and binaries stash/unstash is used.
A exemplary, simplified pseudo pipeline would look like:
pipeline {
agent { label 'basic' }
// Declarative SCM checkout configured in the mutli-branch pipeline job-config
stages {
stage('Build binaries') {
matrix {
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows'
}
}
stages {
stage("Collect sources") {
steps {
<Collect native's sources for ${PLATFORM}> in "${WORKSPACE}/native.sources.${PLATFORM}"
dir("native.sources.${PLATFORM}") {
stash "sources.${PLATFORM}"
}
}
}
stage('Build binaries') {
options { skipDefaultCheckout() }
agent { label "natives-${PLATFORM}" }
steps {
unstash "sources.${PLATFORM}"
<Build native binaries from unstashed sources into 'libs' folder >
dir('libs') {
stash "binaries.${PLATFORM}"
}
}
}
stage('Collect and distribute binaries') {
agent {
<initial/pipeline-agent>
}
steps {
dir("libs.${PLATFORM}") {
unstash "binaries.${PLATFORM}"
}
}
}
}
}
}
stage('Bundle and distribute') {
...
}
}
}
But the question is, how do I tell Jenkins to execute the third stage of the matrix on the initial/pipeline agent again?
If I simply don't specify an agent for the third-stage the execution is:
Stage on Pipeline-Agent
Stage on Native-Build-Agent
Stage on Native-Build-Agent
but I want:
Stage on Pipeline-Agent
Stage on Native-Build-Agent
Stage on Pipeline-Agent
In the syntax-reference I didn't find a agent parameter like agent { <initial/pipeline-agent> }:
https://www.jenkins.io/doc/book/pipeline/syntax/#agent
https://www.jenkins.io/doc/book/pipeline/syntax/#matrix-cell-directives
The agent section describes a boolean option reuseNode, but it is only "valid for docker and dockerfile".
The only workaround I found so far, was to define a second matrix and move the execution of the third stage to that. This works as expect and the stage is executed on the pipeline-agent, but has the drawback that the matrix-stage has to be specified twice as well as its when-conditions.
Appendix
The problem probably also exists, when using per stage agents in an ordinary linear pipeline.

How to invoke the job from one slave(server) to another slave(server) in jenkins

Please, can you advise as I am planning to invoke a job that is on different server. For example:
Slave1 server1: deploy job
Slave2 server2: build job
I want build job trigger the deploy job. Any suggestion, please
If you are trying to run two Jobs in the same Jenkins server. Your Pipeline should look something like below. Here from build Job you can call the Deploy Job.
Build Job
pipeline {
agent { label 'server2' }
stages {
stage('Build') {
steps {
build job: 'DeployJobName'
}
}
}
}
Deploy Job
pipeline {
agent { label 'server1' }
stages {
stage('Deploy') {
steps {
// Deploy something
}
}
}
}
Update
If you want to trigger a Job in a different Jenkins server, you can use a Plugin like RemoteTriggerPlugin or simply using the Jenkins API.
curl http://serer1:8080/job/DeployJobName/build?token=YOUR_REMOTE_TRIGGER_TOKEN
pipeline {
agent { label 'server2' }
stages {
stage('Build') {
steps {
sh 'curl http://server1:8080/job/DeployJobName/build?token=YOUR_REMOTE_TRIGGER_TOKEN'
}
}
}
}

Jenkins / How to deploy with one click

I am working on a project with git and jenkins (pipeline).
I want to build the project at every commit but only deploy it when the chief wants.
So I would like to have like, two pipelines, one that run at every commit and only build / test and one that I can run by clicking on a button labelled "click me to deploy" that do the job.
Do I must create 2 jenkins jobs or is there a plugin or a way to do this with 1 job.
I have searched but I found nothing about this.
You can achieve with 1job using Input Step (Pipeline). As part of your pipeline, after the build and test execution, add input step (Wait for Interactive input) and then add the deployment related stages.
So for each check-in, Jenkins build will trigger. But it will complete only build and test stages after that it will wait for chief approval to proceed for deployment.
reference: https://jenkins.io/doc/pipeline/steps/pipeline-input-step
This is an example on how to build a pipeline that builds, waits for input, and deploys when input is yes. If input timeout is exceeded then the job will exit. If one does not need the timeout then it can be ommited and the pipeline will wait indefinately without consuming an executor (note the agent annotation in the top pipeline and in each stage)
pipeline {
agent none
stages {
stage('Build') {
agent { label 'master' }
steps {
sh 'build something'
}
}
stage('Production deploy confirmation') {
options {
timeout(time: 60, unit: 'SECONDS')
}
input {
message "Deploy to production?"
ok "Yes"
}
steps {
echo 'Confirmed production deploy'
}
}
stage('Deploy Production') {
stage('internal') {
agent { label 'master' }
steps {
sh 'deploy something'
}
}
}
}
}
Try a parametrized Job with a Boolean parameter and two separate stages for Build and Deploy:
pipeline{
parameters {
booleanParam(name: 'deploy_param', defaultValue: false, description: 'Check if want to deploy')
}
stages{
stage("Build"){
steps{
// build steps
}
}
stage("Deploy"){
when {
environment name: 'deploy_param', value: 'true'
}
steps{
// deploy steps
}
}
}
}
In this way yo can have a CI build with "Deploy" stage turned off, as the deploy_param is set to false by default. And also a manual build ("when the chief wants") with "Deploy" stage turned on by manually setting the deploy_param to true.

Mark a stage in Jenkins Pipeline as eg "UNSTABLE" but proceed with future stages?

I'm going to use Jenkins pipeline plugin to test several binaries A B C on several nodes 1 2 3.
In the end of my test I would like to have every single result of all possible combinations. So my Pipe may not abort when a single stage fails. It should proceed.
eg: A1 green, A2 green, A3 red, B1 green, B2 red, ..., C3 green
But when the first binary returns with an value unequal zero ("Binary not working on the system") it's stage is marked as FAILURE and any other stages are skipped.
Is there a possibility in Jenkins Pipeline to mark a stage as "UNSTABLE" but proceed with running the other tests?
According to Continue Jenkins job after failed stage while marking stage as failed can't mark this step as failed. The solution of this in running tasks in parallel is not working for my setup. So is it possible to safely mark it as something else? Is it possible to manipulate the result of a stage?
This question How to continue past a failing stage in Jenkins declarative pipeline syntax intents to use a scripted pipeline. I would like to avoid that if it is possible to do it in an other way.
pipeline {
agent {label 'master'}
stages {
stage('A1') {
agent {label 'Node1'}
steps {
sh 'binA'
}
}
stage('A2') {
agent {label 'Node1'}
steps {
sh 'binB' // If this bin fails, all following stages are skipped
}
}
// ...
stage('C3'){
agent {label 'Node3'}
steps {
sh 'binC'
}
}
}
}
Declarative Pipeline: Though using currentBuild.result = 'UNSTABLE' works in declarative pipelines too, Blue Ocean displays all stages as unstable irrespective of which stage fails.
To mark only specific stages as unstable, use the step unstable(message: String) as described here within your stage and install/update the following plugins:
Pipeline: Basic Steps to 2.16 or newer
Pipeline: API Plugin to 2.34 or newer
Pipeline: Groovy to 2.70 or newer
Pipeline Graph Analysis to 1.10 or newer
Sample pipeline stage:
stage('Sign Code') {
steps {
script {
try {
pwd()
sh "<YOUR SCRIPT HERE>"
}
catch (err) {
unstable(message: "${STAGE_NAME} is unstable")
}
}
}
}
Note: This also marks the overall build status as unstable.
There is now a more elegant solution, that not only allows you to set a stage and the job result to unstable. Using catchError, you can set any combination of stage and build result:
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 mentioned above, you can freely choose the buildResult and stageResult. 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. (Pipeline: Basic Steps needs to be 2.18 or newer)
For scripted pipeline, you can use try .. catch blocks inside the stages and then set currentBuild.result = 'UNSTABLE'
in the exception handler.

How can i use 'parallel' option in jenkins pipeline in the 'post' section?

I looked at many pipeline examples and how to write the post build section in a pipeline script. But never got my answer i was looking for.
I have 4 jobs - say Job A,B,C and D. I want job A to run first, and if successful it should trigger Job B,C,D in parallel. If Job A fails, it should trigger only Job B. Something like below:
pipeline {
agent any
stages {
stage('Build_1') {
steps {
sh '''
Build Job A
'''
}
}
post {
failure {
sh '''
Build Job B
'''
}
success {
sh '''
Build Job B,C,D in parallel
'''
}
}
}
I tried using 'parallel' option in post section but it gave me errors. Is there a way to build Job B,C,D in parallel, in the post 'success' section?
Thanks in advance!
The parallel keyword actually can work inside a post condition as long as it is encapsulated inside a script block, as the script blocks is just a fallback to the scripted pipeline which will allow you to run parallel execution step wherever you want.
The following should work fine:
pipeline {
agent any
stages {
stage('Build_1') {
steps {
// Build Job A
}
}
}
post {
failure {
// run job B
build job: 'Job-B'
}
success {
script {
// run jobs B, C, D in parallel
def jobs = ['Job-B', 'Job-C', 'Job-D']
parallel jobs.collectEntries { job ->
["Building ${job}" : {
build job: job
}]
}
}
}
}
}
This is just an example and specific parameters or configuration (for the build keyword) can be added to each job execution according to your needs.
The error message is quiet clear about this:
Invalid step "parallel" used - not allowed in this context - The
parallel step can only be used as the only top-level step in a stages
step
The more restrictive declarative syntax does not allow the usage of parallel in thw post section at the moment.
If you don't want to switch to the scripted syntax, another option that should work: Build the jobs B,C,D in parallel in a second stage and move the the failure condition in the post section of your first stage. As a result job B,C,D will run if A is successful. If A is not successful only job B will run.
pipeline {
agent any
stages {
stage('one') {
steps {
// run job A
}
post {
failure {
// run job B
}
}
}
stage('two') {
steps {
parallel(
// run job B, C, D
)
}
}
}
}

Resources