Is it possible to get a specific stage in a jenkins pipeline triggered? - jenkins

I have a maven dependency graph where each of the dependency has a separate git repository.
I created each as a separate maven job and specified downstream job so that whenever a job gets triggered, the downstream jobs also get triggered recursively.
I want to achieve the same using script.
I created a pipeline script and defined all the nodes as stages.
stages {
stage('A') {
steps {
checkoutAndBuild('A.git', 'A')
}
}
stage('Parallel - B, C') {
parallel {
stage('B') {
steps {
checkoutAndBuild('B.git', 'B')
}
}
stage('C') {
steps {
checkoutAndBuild('C.git', 'C')
}
}
}
}
stage('D') {
steps {
checkoutAndBuild('D.git', 'D')
}
}
}
I want if commit happens in B - only B and D get triggered
And if commit happens in A - the whole pipeline gets triggered.
Please suggest if I can achieve the desired behavior using script

Related

Jenkinsfile - How to make a cron trigger kick off only a specifc stage?

I have a Jenkinsfile with the following triggers:
triggers {
cron('0 * * * 1-5')
}
So it will trigger at the top of the hour, every hour, Monday through Friday.
In the Jenkinsfile I have a number of stages like:
stage('CI Build and push snapshot') {
when {
anyOf { branch 'PR-*';branch 'develop' }
}
.
.
.
stage('Build Release') {
when {
branch 'master'
}
.
.
.
stage('Integration Tests') {
when {
? // not sure what goes here
}
What I want to do is, when that trigger is kicked off, I only want the Integration Tests stage to run. How do I achieve this? I think with what I have now every stage is going to be run.
Thanks!
I was able to get it working using something like:
stage('CI Build and push snapshot') {
when {
anyOf { branch 'PR-*';branch 'develop' }
not {
expression { return currentBuild.rawBuild.getCause(hudson.triggers.TimerTrigger$TimerTriggerCause) }
}
}
stage('Integration Tests') {
when {
branch 'develop'
expression { return currentBuild.rawBuild.getCause(hudson.triggers.TimerTrigger$TimerTriggerCause) }
}
Note this is using shared library functions and scripted syntax (not declarative), you will need to use script {} blocks in order to implement.
For organisation purposes, I put this into its own function in a shared library file called jobCauses.groovy under /vars, you can keep it in-line if you like, or put it at the bottom of the Jenkinsfile etc.
/**
* Checks if job cause is Cron
*
* #return boolean
*/
boolean hasTriggeredCause() {
List jobCauses = currentBuild.rawBuild.getCauses().collect { it.getClass().getCanonicalName().tokenize('.').last() }
return jobCauses.contains('TimerTriggerCause')
}
Then in your pipeline:
stage('Integration Tests') {
script {
if ( jobCauses.hasTriggeredCause() ) {
//do the thing
}
}
}

Re-use agent in parallel stages of declarative pipeline

I'm using Declarative Pipelines 1.3.2 plugin and I want to use the same agent (as in only specifying the agent directive once) in multiple parallel stages:
stage('Parallel Deployment')
{
agent { dockerfile { label 'docker'; filename 'Dockerfile'; } }
parallel
{
stage('A') { steps { ... } }
stage('B') { steps { ... } }
}
}
However, Jenkins complains:
"agent" is not allowed in stage "Parallel Deployment" as it contains parallel stages
A solution is to duplicate the agent directive for each parallel stage, but this is tedious and leads to lot of duplicated code with many parallel stages:
stage('Parallel Deployment')
{
parallel
{
stage('A') {
agent { dockerfile { label 'docker'; filename 'Dockerfile'; } }
steps { ... }
}
stage('B') {
agent { dockerfile { label 'docker'; filename 'Dockerfile'; } }
steps { ... }
}
}
}
Is there a more idiomatic solution, or is duplicating agent directive necessary for each of the parallel stages?
Declare the agent at Pipeline level so all stages run on the same agent.

Locking parallelised stages in Jenkins

We're trying to write a declarative Jenkinsfile build script to run several steps in parallel in each of several stages, however we need to prevent multiple builds from running at the same time because they depend on the same resource. Hence, we've tried to use locking to lock all of the stages such that a build can finish completely before another one attempts to use the same resources.
However, we've found that locking stages requires nesting the stages in a parent and that parallel steps can only be included in a top-level stage:
WorkflowScript: 24: Parallel stages or branches can only be included in a top-level stage
Essentially what we're trying to do is this:
#!/usr/bin/env groovy
pipeline {
agent any
stages {
stage('parent') {
options {
lock('resource')
}
stages {
stage('build') {
steps {
parallel(
'app1': { build("app1") },
'app2': { build("app2") },
)
}
}
stage('deploy') {
steps {
parallel(
'app1': { deploy("app1") },
'app2': { deploy("app2") },
)
}
}
}
}
}
}
Are there any workarounds to achieve this behaviour?
Does this fix your problem?
pipeline {
agent any
options {
lock('resource')
}
stages {
stage('build') {
parallel {
stage('app1') {
steps {
echo("build app1")
}
}
stage('app2') {
steps {
echo("build app2")
}
}
}
}
stage('deploy') {
parallel {
stage('app1') {
steps {
echo("deploy app1")
}
}
stage('app2') {
steps {
echo("deploy app2")
}
}
}
}
}
}
You might need to update to the latest pipeline code
This locks the resource for the whole job. If you want to lock the resource for each of the parallel stages, I would suggest the stages are not parallel

Creating a sequential step in a jenkins declarative pipeline preceding a parallel stage

I would like to setup parallel stages as described in the image
In this instance, the setup is pretty heavy so has to be done once before the parallel group starts of G1, G2 and G3. At the same time, the stage : Initial Checks has 2 items that I would like to run in parallel.
Is this possible in the Declarative Pipeline or do I have to resort to a script?
I couldnt see in the documentation the ability for this to work
Stages {
stage ('P1') {
}
stage ('P2 Setup') {}
stage ('P2') {
//Here it can contain either Steps or Parallel. I can only do
parallel {
stage ('g1') {} //Parallel tests
stage ('g2') {}
stage ('g3') {}
}
}
stage ('P2 Cleanup') {}
}
Have you encountered similar situations and what have your solutions been like?
Ofcourse 1 solution is to make Setup and Cleanup as part of every group, but like I said, its pretty intensive and I would only take it on if what the diagram indicates isn't possible.
Solution 2
stage ('p2') {
script {
//Some scripting here to get the result?
}
}
Pipeline
This is not supported by a DSL or declarative pipeline yet. You are essentially looking for nested parallel stages as mentioned here
Issue is still open with Jenkins community which you can watch here
In your given case, you can launch stage P1 and stage setup in parallel. However, it is important to start P1 as a background process because from your graph it appears that P1 is a time-intensive operation. Once group stage completes, you can collect the status of P1 and proceed to S2.
stages{
stage('Build'){
steps{
echo "Build"
}
}
stage('Init'){
parallel{
stage('P1'){steps{ echo "launch p1 in background"}}
stage('setup'){steps{echo "setup"}}
}
}
stage('Group'){
parallel{
stage('P1'){steps{echo "p1"}}
stage('P2'){steps{echo "p2"}}
stage('P3'){steps{echo "p3"}}
}
}
stage('Cleanup'){
steps{
echo "cleanup"
}
}
stage('Check P1 status'){
steps{
echo "Check"
}
}
stage('S2'){
steps{
echo "S2"
}
}
}
I think you are looking for this
node {
stage("P1"){}
stage("p2") {}
stage("p3") {
parallel (
"firstTask" : {
},
"secondTask" : {
}
)
}
}

Trigger jenkins hudson.model.Job programmatically from jenkins plugin

I am struggling to figure out some sample example to trigger hudson.model.Job from plugin:
private void triggerPipelineJobs(){
for (Job<?,?> job : Jenkins.getInstance().getAllItems(Job.class)) {
System.out.println("job is : " + job.getName());
//how to trigger this jenkins pipeline job
}
}
To run all Jenkins jobs (including pipelines), I use the following:
import hudson.model.*;
// get all jobs
jobs = Hudson.instance.getAllItems(Job.class);
// iterate through the jobs
for (j in jobs) {
// first check, if job is buildable
if (j instanceof BuildableItem) {
// run that job
j.scheduleBuild();
}
}
I think the part you are looking for is the scheduleBuild() method which you could call on your job variable in your for loop.

Resources