<p>I modified your Jenkins file as shown below. </p>

<pre><code>pipeline {
agent { label 'agent01'}
stages {
    stage('build') {
        steps {
            echo "build"
            sh "ls -lrt &amp;&amp; touch build.txt"
        }
    }
    stage('test') {
        parallel {
            stage('unit tests') {
                steps {
                    echo "unit tests"
                    sh "ls -lrt &amp;&amp; touch ut.txt"
                    sleep(time:10,unit:"SECONDS")
                }
            }
            stage('integration tests') {
                steps {
                    echo "integration tests"
                    sh "ls -lrt &amp;&amp; touch it.txt"
                    sleep(time:10,unit:"SECONDS")
                }
            }
        }
    }
    stage('deploy staging') {
        agent { label 'master' }
        steps {
            echo "deploy staging"
            sh "ls -lrt &amp;&amp; touch dep.txt"
        }
    }
    stage('confirm release') {
        agent { label 'master' }
        steps {
            echo "RELEASE?"
            sh "ls -lrt &amp;&amp; touch release.txt"
        }
    }
    stage('deploy production') {
        steps {
            echo "deploy production"
            sh "ls -lrt &amp;&amp; touch produ.txt"
        }
    }
}
}
</code></pre>

<ol>
<li>You need not stash and unstash files since it runs on same node and
    workspace. </li>
<li>Use a general node for all the stages except for the one that needs a user input.</li>
</ol>

<p>The output is </p>

<pre><code>    Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on agent01 in /var/jenkins_home/workspace/sandbox-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (build)
[Pipeline] echo
build
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
+ touch build.txt
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (test)
[Pipeline] parallel
[Pipeline]     [unit tests] { (Branch: unit tests)
[Pipeline]     [integration tests] { (Branch: integration tests)
[Pipeline]     [unit tests] stage
[Pipeline]     [unit tests] { (unit tests)
[Pipeline]     [integration tests] stage
[Pipeline]     [integration tests] { (integration tests)
[Pipeline]     [unit tests] echo
[unit tests] unit tests
[Pipeline]     [unit tests] sh
[unit tests]     [sandbox-pipeline] Running shell script
[Pipeline]     [integration tests] echo
[integration tests] integration tests
[Pipeline]     [integration tests] sh
[unit tests] + ls -lrt
[unit tests] total 0
[unit tests] -rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 build.txt
[unit tests] + touch ut.txt
[integration tests]     [sandbox-pipeline] Running shell script
[Pipeline]     [unit tests] sleep
[integration tests] + ls -lrt
[integration tests] total 0
[integration tests] -rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 build.txt
[integration tests] -rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 ut.txt
[integration tests] + touch it.txt
[unit tests] Sleeping for 10 sec
[Pipeline]     [integration tests] sleep
[integration tests] Sleeping for 10 sec
[Pipeline]     [unit tests] }
[Pipeline]     [unit tests] // stage
[Pipeline]     [unit tests] }
[Pipeline]     [integration tests] }
[Pipeline]     [integration tests] // stage
[Pipeline]     [integration tests] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (deploy staging)
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/sandbox-pipeline
[Pipeline] {
[Pipeline] echo
deploy staging
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
+ touch dep.txt
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (confirm release)
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/sandbox-pipeline
[Pipeline] {
[Pipeline] echo
RELEASE?
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
-rw-r--r-- 1 jenkins 115 0 Oct 19 13:58 dep.txt
+ touch release.txt
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (deploy production)
[Pipeline] echo
deploy production
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
-rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 build.txt
-rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 ut.txt
-rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 it.txt
+ touch produ.txt
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
</code></pre>

CC BY-SA 4.0
2021-06-08T15:10:34.813Z
Is this actually valid? I haven't tried it, but my impression is that you can't define an agent in a child scope once one has been defined in a parent. The exception being that you _can_ target specific agents using `node(...)` inside a `script { ... }` block. Can anyone clarify?
Max Cascone
CC BY-SA 4.0
2021-06-08T16:03:44.180Z
@MaxCascone The code I provided above is tested and the log also confirms that you can choose different agents. Please note that it is a declarative pipeline.
Ram
CC BY-SA 4.0
2018-10-19T14:05:36.757Z
2018-10-19T14:05:36.757Z
Ram
<p>I've been using a Jenkins pipeline with a parallel step for testing like this:</p>

<pre><code>pipeline {
    agent { label 'php' }
    stages {
        stage('build') {
            steps {
                ...
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    steps {
                        ...
                    }
                }
                stage('integration tests') {
                    steps {
                        ...
                    }
                }
            }
        }
        stage('deploy') {
            steps {
                ...
            }
        }
    }
}
</code></pre>

<p>The pipeline runs fine on a single agent, but now I want to add a step with manual input, which should not keep the agent running. The agents are cloud servers that get started and stopped on demand.</p>

<p>To do so, I assigned "none" agent to the pipeline and the actual agent to all stages but the one requesting input:</p>

<pre><code>pipeline {
    agent none
    stages {
        stage('build') {
            agent { label 'php' }
            steps {
                ...
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    agent { label 'php' }
                    steps {
                        ...
                    }
                }
                stage('integration tests') {
                    agent { label 'php' }
                    steps {
                        ...
                    }
                }
            }
        }
        stage('deploy staging') {
            agent { label 'php' }
            steps {
                ...
            }
        }
        stage('confirm release') {
            steps {
                input { message 'release?' }
            }
        }
        stage('deploy production') {
            agent { label 'php' }
            steps {
                ...
            }
        }
    }
}
</code></pre>

<p>Artifacts that are needed in a following stage are carried over with <code>stash</code> and <code>unstash</code>. This works, but with two nuisances:</p>

<ol>
<li>Stashing and unstashing between each single stage causes overhead. I would rather have all stages until the manual input executed in a single workspace. But <code>agent</code> is only allowed in stages that contain steps.</li>
<li>Each parallel stage blocks a single agent. So if there is only one free agent, there is no parallel execution, unlike before.</li>
</ol>

<p>I can live with (1) if it's not possible otherwise, but parallel execution on one agent is important for me. Is it possible somehow in my current setup? If not, what are my options to achieve something similar?</p>

<jenkins><jenkins-pipeline><deployment>
Parallel stages running on same agent in Jenkins declarative pipeline
Fabian Schmengler
# Parallel stages running on same agent in Jenkins declarative pipeline

(Asked by: username_0 on 2018-09-29)

I've been using a Jenkins pipeline with a parallel step for testing like this:
pipeline {
    agent { label 'php' }
    stages {
        stage('build') {
            steps {
                ...
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    steps {
                        ...
                    }
                }
                stage('integration tests') {
                    steps {
                        ...
                    }
                }
            }
        }
        stage('deploy') {
            steps {
                ...
            }
        }
    }
}

The pipeline runs fine on a single agent, but now I want to add a step with manual input, which should not keep the agent running. The agents are cloud servers that get started and stopped on demand.
To do so, I assigned "none" agent to the pipeline and the actual agent to all stages but the one requesting input:
pipeline {
    agent none
    stages {
        stage('build') {
            agent { label 'php' }
            steps {
                ...
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    agent { label 'php' }
                    steps {
                        ...
                    }
                }
                stage('integration tests') {
                    agent { label 'php' }
                    steps {
                        ...
                    }
                }
            }
        }
        stage('deploy staging') {
            agent { label 'php' }
            steps {
                ...
            }
        }
        stage('confirm release') {
            steps {
                input { message 'release?' }
            }
        }
        stage('deploy production') {
            agent { label 'php' }
            steps {
                ...
            }
        }
    }
}

Artifacts that are needed in a following stage are carried over with stash and unstash. This works, but with two nuisances:

Stashing and unstashing between each single stage causes overhead. I would rather have all stages until the manual input executed in a single workspace. But agent is only allowed in stages that contain steps.
Each parallel stage blocks a single agent. So if there is only one free agent, there is no parallel execution, unlike before.

I can live with (1) if it's not possible otherwise, but parallel execution on one agent is important for me. Is it possible somehow in my current setup? If not, what are my options to achieve something similar?

**Tags:** jenkins, jenkins-pipeline, deployment


---

## 1 answers

### Answer by username_1 on 2018-10-19. Score: 2

I modified your Jenkins file as shown below. 
pipeline {
agent { label 'agent01'}
stages {
    stage('build') {
        steps {
            echo "build"
            sh "ls -lrt && touch build.txt"
        }
    }
    stage('test') {
        parallel {
            stage('unit tests') {
                steps {
                    echo "unit tests"
                    sh "ls -lrt && touch ut.txt"
                    sleep(time:10,unit:"SECONDS")
                }
            }
            stage('integration tests') {
                steps {
                    echo "integration tests"
                    sh "ls -lrt && touch it.txt"
                    sleep(time:10,unit:"SECONDS")
                }
            }
        }
    }
    stage('deploy staging') {
        agent { label 'master' }
        steps {
            echo "deploy staging"
            sh "ls -lrt && touch dep.txt"
        }
    }
    stage('confirm release') {
        agent { label 'master' }
        steps {
            echo "RELEASE?"
            sh "ls -lrt && touch release.txt"
        }
    }
    stage('deploy production') {
        steps {
            echo "deploy production"
            sh "ls -lrt && touch produ.txt"
        }
    }
}
}


You need not stash and unstash files since it runs on same node and
    workspace. 
Use a general node for all the stages except for the one that needs a user input.

The output is 
    Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on agent01 in /var/jenkins_home/workspace/sandbox-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (build)
[Pipeline] echo
build
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
+ touch build.txt
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (test)
[Pipeline] parallel
[Pipeline]     [unit tests] { (Branch: unit tests)
[Pipeline]     [integration tests] { (Branch: integration tests)
[Pipeline]     [unit tests] stage
[Pipeline]     [unit tests] { (unit tests)
[Pipeline]     [integration tests] stage
[Pipeline]     [integration tests] { (integration tests)
[Pipeline]     [unit tests] echo
[unit tests] unit tests
[Pipeline]     [unit tests] sh
[unit tests]     [sandbox-pipeline] Running shell script
[Pipeline]     [integration tests] echo
[integration tests] integration tests
[Pipeline]     [integration tests] sh
[unit tests] + ls -lrt
[unit tests] total 0
[unit tests] -rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 build.txt
[unit tests] + touch ut.txt
[integration tests]     [sandbox-pipeline] Running shell script
[Pipeline]     [unit tests] sleep
[integration tests] + ls -lrt
[integration tests] total 0
[integration tests] -rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 build.txt
[integration tests] -rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 ut.txt
[integration tests] + touch it.txt
[unit tests] Sleeping for 10 sec
[Pipeline]     [integration tests] sleep
[integration tests] Sleeping for 10 sec
[Pipeline]     [unit tests] }
[Pipeline]     [unit tests] // stage
[Pipeline]     [unit tests] }
[Pipeline]     [integration tests] }
[Pipeline]     [integration tests] // stage
[Pipeline]     [integration tests] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (deploy staging)
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/sandbox-pipeline
[Pipeline] {
[Pipeline] echo
deploy staging
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
+ touch dep.txt
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (confirm release)
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/sandbox-pipeline
[Pipeline] {
[Pipeline] echo
RELEASE?
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
-rw-r--r-- 1 jenkins 115 0 Oct 19 13:58 dep.txt
+ touch release.txt
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (deploy production)
[Pipeline] echo
deploy production
[Pipeline] sh
[sandbox-pipeline] Running shell script
+ ls -lrt
total 0
-rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 build.txt
-rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 ut.txt
-rw-r--r-- 1 jenkins docker 0 Oct 19 13:53 it.txt
+ touch produ.txt
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

> **Comments:**
> **username_2**: Is this actually valid? I haven't tried it, but my impression is that you can't define an agent in a child scope once one has been defined in a parent. The exception being that you _can_ target specific agents using `node(...)` inside a `script { ... }` block. Can anyone clarify?  
> **username_1**: @MaxCascone The code I provided above is tested and the log also confirms that you can choose different agents. Please note that it is a declarative pipeline.  

---

