The problem in your original code is that the stages you create (more 
specifically the closures for the stages) reference the mutable repo_name 
variable directly, and so after you create all the stages in the loop, 
repo_name’s value is the final repo in repo_names, so when the stages are 
executed they all use the same value of repo_name. 

You need to modify the script so that the stages do not refer to the loop 
variable directly, usually by creating a copy of the loop variable, but 
approaches like using collectEntries or passing the loop variable as an 
argument to a closure that creates another closure would also fix the issue.

Here is a simplified example of this problem in raw Groovy. 
<http://groovyconsole.appspot.com/script/5174765568393216>

Here is an example of an easy way to fix the issue in the simplified example 
<http://groovyconsole.appspot.com/script/5092652974342144>. 


> On Jun 11, 2020, at 10:00, Roman O <[email protected]> wrote:
> 
> The following code worked for me after following the example from docs 
> <https://www.jenkins.io/doc/pipeline/examples/#parallel-from-list>:
> 
>     pipeline {
>         agent any 
>         options {
>             ansiColor('xterm')                    
>         }
>         parameters {
>             extendedChoice description: '', multiSelectDelimiter: ',', name: 
> 'REPO_NAMES', quoteValue: false,saveJSONParameterToFile: false, type: 
> 'PT_CHECKBOX', value: 'repo1,repo2,repo3', visibleItemCount: 3
>         }
>     
>         stages {
>             stage('Prepare repos to run on') {
>                 
>                 steps { 
>                     script {  
>                         def repo_names = params.REPO_NAMES.split(',')
>                         def single_repo_jobs = repo_names.collectEntries {
>                             ["${it}" : 
>                                 {  
>                                     catchError {                              
>               
>                                             stage(it) {   
>                                                 build job: 
> 'check-single-repo',
>                                                         parameters:
>                                                                 [             
>                                        
>                                                                         
> string(name:'REPO_NAME', value: "${it}")
>                                                                 ] 
>                                             }                                 
>            
>                                     }
>                                 }                        
>                             ]
>                         }                    
>                         parallel single_repo_jobs        
>                     }                
>                 }
>                            
>             }
>         }
>     }
> 
> 
> 
> 
> On Thursday, June 11, 2020 at 4:49:15 PM UTC+3, Roman O wrote:
> My goal is to run the same job check-single-repo on multiple repositories in 
> parallel.
> 
> Below pipeline doesn't seem to achieve the goal:
> 
>     pipeline {
>         agent any 
>         options {
>             ansiColor('xterm')                    
>         }
>         parameters {
>             extendedChoice description: '', multiSelectDelimiter: ',', name: 
> 'REPO_NAMES', quoteValue: false,saveJSONParameterToFile: false, type: 
> 'PT_CHECKBOX', value: 'repo1,repo2,repo3', visibleItemCount: 3
>         }
>     
>         stages {
>             stage('Prepare repos to run on') {
>                 
>                 steps { 
>                     script {  
>                         repo_names = params.REPO_NAMES.split(',')
>                         def single_repo_jobs = [:]
>                         for (repo_name in repo_names) {
>                             println repo_name
>                             single_repo_jobs[repo_name] = {  
>                                     stage(repo_name) {    
>                                         catchError {
>                                             build job: 'check-single-repo',
>                                                     parameters:
>                                                             [                 
>                                    
>                                                                     
> string(name:'REPO_NAME', value: repo_name)
>                                                             ] }
>                                         }
>                                     }
>                         }
>                         println single_repo_jobs
>                         parallel single_repo_jobs                        
>                     }                
>                 }
>                            
>             }
>         }
>     }
> 
> 
> Its output:
> 
>     ...
>     repo1
>     repo2
>     repo3
>     {repo1=org.jenkinsci.plugins.workflow.cps.CpsClosure2@3a396959, 
> repo2=org.jenkinsci.plugins.workflow.cps.CpsClosure2@1a4b5000, 
> repo3=org.jenkinsci.plugins.workflow.cps.CpsClosure2@1d034ac}
>     [Pipeline] parallel
>     [Pipeline] { (Branch: repo1)
>     [Pipeline] { (Branch: repo2)
>     [Pipeline] { (Branch: repo3)
>     [Pipeline] stage
>     [Pipeline] { (repo3)
>     [Pipeline] stage
>     [Pipeline] { (repo3)
>     [Pipeline] stage
>     [Pipeline] { (repo3)
>     [Pipeline] catchError
>     [Pipeline] {
>     [Pipeline] catchError
>     [Pipeline] {
>     [Pipeline] catchError
>     [Pipeline] {
>     [Pipeline] build (Building check-single-repo)
>     Scheduling project: check-single-repo
>     [Pipeline] build (Building check-single-repo)
>     Scheduling project: check-single-repo
>     [Pipeline] build (Building check-single-repo)
>     Scheduling project: check-single-repo
>     
>     Starting building: check-single-repo #230
>     Starting building: check-single-repo #230
>     Starting building: check-single-repo #230
>     
>     [Pipeline] }
>     check-single-repo #230 repo3 completed with status UNSTABLE (propagate: 
> false to ignore)
>     [Pipeline] }
>     check-single-repo #230 repo3 completed with status UNSTABLE (propagate: 
> false to ignore)
>     [Pipeline] }
>     check-single-repo #230 repo3 completed with status UNSTABLE (propagate: 
> false to ignore)
>     ...
> 
> 
> As it invokes only one pipeline #230 on repo3
> 
> 
> How to run the same Jenkins job on different repositories in parallel using 
> Declarative Pipeline?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected] 
> <mailto:[email protected]>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/jenkinsci-users/d094696f-9984-4e0e-9189-66c06aee8dado%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/jenkinsci-users/d094696f-9984-4e0e-9189-66c06aee8dado%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
You received this message because you are subscribed to the Google Groups 
"Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jenkinsci-users/6232FF71-658F-4FB1-8EEC-7C3BE3D3CEE1%40cloudbees.com.

Reply via email to