Parameterized pipeline job has to take more than one job name as parameter and start parameterized jobs in parallel, I tried below code but it isnt working
def String[] jobs;
stages {
stage('stage1') {
steps {
script {
jobs = jobnames.split(',');
for (ii = 0; ii < jobs.size(); ii++) {
build job: 'startjob_${jobs[ii]}', parameters: [string(name: 'BRANCH',value: String.valueOf(BRANCH)),string(name: 'CHANGENUM',value: String.valueOf(CHANGENUM))]
}
This code is working, but not the way I expected, I want to start all jobs in parallel. but its scheduling one job after other.
can anyone help me with this
Try this
builds = [:]
for (ii = 0; ii < jobs.size(); ii++) {
builds << [
"startjob_${jobs[ii]}": { ->
build job: "startjob_${jobs[ii]}", parameters: [string(name: 'BRANCH', value: String.valueOf(BRANCH)), string(name: 'CHANGENUM', value: String.valueOf(CHANGENUM))]
}
]
}
parallel builds
Related
I am trying to create a pipeline in Jenkins which triggers same job multiple times in different node(agents).
I have "Create_Invoice" job Jenkins, configured : (Execute Concurrent builds if necessary)
If I click on Build 10 times it will run 10 times in different (available) agents/nodes.
Instead of me clicking 10 times, I want to create a parallel pipeline.
I created something like below - it triggers the job but only once.
What Am I missing or is it even possible to trigger same test more than once at the same time from pipeline?
Thank you in advance
node {
def notifyBuild = { String buildStatus ->
// build status of null means successful
buildStatus = buildStatus ?: 'SUCCESSFUL'
// Default values
def tasks = [:]
try {
tasks["Test-1"] = {
stage ("Test-1") {
b = build(job: "Create_Invoice", propagate: false).result
}
}
tasks["Test-2"] = {
stage ("Test-2") {
b = build(job: "Create_Invoice", propagate: false).result
}
}
parallel tasks
} catch (e) {
// If there was an exception thrown, the build failed
currentBuild.result = "FAILED"
throw e
}
finally {
notifyBuild(currentBuild.result)
}
}
}
I had the same problem and solved it by passing different parameters to the same job. You should add parameters to your build steps, although you obviously don't need them. For example, I added a string parameter.
tasks["Test-1"] = {
stage ("Test-1") {
b = build(job: "Create_Invoice", parameters: [string(name: "PARAM", value: "1")], propagate: false).result
}
}
tasks["Test-2"] = {
stage ("Test-2") {
b = build(job: "Create_Invoice", parameters: [string(name: "PARAM", value: "2")], propagate: false).result
}
}
As long as the same parameters or no parameters are passed to the same job, the job is only tirggered once.
See also this Jenkins issue, it describes the same problem:
https://issues.jenkins.io/browse/JENKINS-55748
I think you have to switch to Declarative pipeline instead of Scripted pipeline.
Declarative pipeline has parallel stages support which is your goal:
https://www.jenkins.io/blog/2017/09/25/declarative-1/
This example will grab the available agent from the Jenkins and iterate and run the pipeline in all the active agents.
with this approach, you no need to invoke this job from an upstream job many time to build on a different agent. This Job itself will manage everything and run all the stages define in all the online node.
jenkins.model.Jenkins.instance.computers.each { c ->
if(c.node.toComputer().online) {
node(c.node.labelString) {
stage('steps-one') {
echo "Hello from Steps One"
}
stage('stage-two') {
echo "Hello from Steps Two"
}
}
} else {
println "SKIP ${c.node.labelString} Because the status is : ${c.node.toComputer().online} "
}
}
My Jenkins job run multiple builds in parallel as below:
def branches = [:]
for (int i = 0; i < 4; i++) {
def index = i
branches["branch${i}"] = {
build job: 'Test', parameters: [
string(name: 'param1', value:'test_param'),
string(name:'dummy', value: "${index}")]
}
}
parallel branches
For the above code I want to print all build result. So how can I get build result (e.g. SUCCESS, FAILURE...) of all parallel jobs?
If you want to print all branches result in the same console
you can do it like this
def branches = [:]
for (int i = 0; i < 4; i++) {
def index = i
branches["branch${i}"] = {
build job: 'Test', parameters: [
string(name: 'param1', value:'test_param'),
string(name:'dummy', value: "${index}")]
}
println currentBuild.result
}
parallel branches
currentBuild.result holds status of the build so if you print it in each branch you will get what you need. If the stage
I have a pipeline job which run some sequence of action (Eg; Build >> Run >> Report). I ahave put this sequence in a for loop as I can get a parameter how many times I should repeat the same sequence. Please find the sample code I have written.
for (int i = 0; i < <param_val>; ++i){
node{
stage('Build') {
build 'Build'
}
stage('Run') {
build 'Run'
}
stage('Reporting') {
build 'Reporting'
}
}
}
Now my code is waiting for one complete sequence to happen and then continue to run the next sequence. That is time consuming. I have more slave agents and can run the sequence in parallel. How can I run each iteration of a for loop parallel?
I have thought of a solution :
have a pipeline having the actual sequence
node{
stage('Build') {
build 'Build'
}
stage('Run') {
build 'Run'
}
stage('Reporting') {
build 'Reporting'
}
}
have another pipeline with the for loop which will trigger the 1st pipeline with wait: false:
for (int i = 0; i < <param_val>; ++i){
build(job: 'pipeline-1', wait: false)
}
Does this work ? Or do we have a better option to do the same with single pipeline ?
Put the code inside the loop in a closure:
def oneNode = { c ->
node {
build job: 'Build', parameters: [string(name: 'Component', value: c)]
build 'Run'
build 'Reporting'
}
}
Then make a map of all the closures you want to run simultaneously:
def jobs = [:]
def components = params.Componets.split(",")
for (int i = 0; i < components.size(); ++i) {
def component = components[i].trim()
jobs[component] = {
oneNode(component)
}
}
And finally use the parallel step with the resulting map:
stage('Build, run, report') {
<the code from the above steps>
parallel jobs
}
This worked for me.
def jobs = [:]
def components = params.Componets.split(",")
stage('Build, run, report') {
for (int i = 0; i < components.size(); ++i) {
def index = i
def component = components[index].trim()
jobs[i] = {
node {
build job: 'Build', parameters: [string(name: 'Component', value: component)]
build 'Run'
build 'Reporting'
}
}
}
parallel jobs
}
I have a pipeline which has two parallel run in sequence.
Setup in many slaves in parallel and after all the machine setup is done I have a Build and run stage as coded below. But when I tried running the script I am getting error java.lang.IllegalArgumentException: Expected a closure or failFast but found 0=org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper.
Code for reference:
def slaves = params.slaves
stage('Setup'){
for(int i=0; i<slaves.size(); ++i){
def slave = slaves[i]
setup_builds[i] = build job: 'setup', parameters: [[$class: 'LabelParameterValue', name: 'TestMachine', label: slave]]
}
parallel setup_builds
}
stage('Build, run) {
for (int i = 0; i < 4; ++i){
def index = i
builds[i] = {
stage('Build') {
build job: 'Build'
}
stage('Run') {
build job: 'Run', parameters: [string(name: 'index', value: index)]
}
}
}
parallel builds
}
I have tried using setup_builds.failFast = true and builds.failFast = true before parallel setup_builds and parallel builds. But even that didn't fix the issue.
I think one of the issues is that it expects a closure on the setup_builds level:
setup_builds[i] = { build job: 'setup' ... }
To explain the issue, consider that I have 2 jenkins jobs.
Job1 : PARAM_TEST1
it accepts a parameterized value called 'MYPARAM'
Job2: PARAM_TEST2
it also accepts a parameterized value called 'MYPARAM'
Sometimes I am in need of running these 2 jobs in sequence - so i created a separate pipeline job as shown below. It works just fine.
it also accepts a parameterized value called 'MYPARAM' to simply pass it to the build job steps.
pipeline {
agent any
stages {
stage("PARAM 1") {
steps {
build job: 'PARAM_TEST1', parameters: [string(name: 'MYPARAM', value: "${params.MYPARAM}")]
}
}
stage("PARAM 2") {
steps {
build job: 'PARAM_TEST2', parameters: [string(name: 'MYPARAM', value: "${params.MYPARAM}")]
}
}
}
}
My question:
This example is simple. Actually I have 20 jobs. I do not want to repeat parameters: [string(name: 'MYPARAM', value: "${params.MYPARAM}")] in every single stage.
Is there any way to set the parameters for all the build job steps in one single place?
What you could do is place the common params on the pipeline level and add specific ones to those in the stages
pipeline {
agent any
parameters {
string(name: 'PARAM1', description: 'Param 1?')
string(name: 'PARAM2', description: 'Param 2?')
}
stages {
stage('Example') {
steps {
echo "${params}"
script {
def myparams = params + string(name: 'MYPARAM', value: "${params.MYPARAM}")
build job: 'downstream-pipeline-with-params', parameters: myparams
}
}
}
}
}