I have few parallel stages under which there are multiple sequential stages. Only thing that differs within those stages is few environment variables. Here is how my code looks like
#!groovy
@Library(<sharedLib>) _
def GIT_COMMIT_EMAIL
pipeline {
agent none
parameters {
booleanParam(name: 'uninstall_package', defaultValue: false)
booleanParam(name: 'install_package', defaultValue: false)
booleanParam(name: 'managed_package', defaultValue: false)
booleanParam(name: 'compile_apex', defaultValue: false)
booleanParam(name: 'clear_org', defaultValue: false)
string(name: 'namespace', defaultValue: '', description: 'Package namespace')
string(name: 'version', defaultValue: '', description: 'Package version')
string(name: 'org', defaultValue: 'beta', description: 'org')
string(name: 'gitbranch', defaultValue: 'master', description: 'Git Branch to build from')
string(name: 'retry', defaultValue: '3', description: 'Number Of Retries/Reruns for failed Pytest')
string(name: 'pw_version', defaultValue: 'latest', description: 'Playwright Version')
}
options {
buildDiscarder(logRotator(artifactNumToKeepStr: '10'))
disableConcurrentBuilds()
timestamps()
timeout(time: 3, unit: 'HOURS')
}
stages {
stage("Installing & Running Tests Stage")
{
agent {
docker {
args "${DOCKER_PARAMS}"
image <image>
label <label
registryCredentialsId <credential>
registryUrl <url>
}
}
stages {
// No Cleanup As Docker is run with root user and as a result generated folders/files get root ownership
stage('Checkout SCM') {
steps {
echo "Checkout"
}
}
stage("Setup and Run Tests in Parallel"){
stages{
stage('Setup CCI for Org') {
steps{
setup_cci_org()
}
}
stage("Create Scratch org and Run tests"){
parallel {
stage("Running against Auto_org_1"){
environment{
auto_org_name = "auto_org_1"
auto_org_kexpr = "${params.kexpr1}"
}
stages{
stage('Create Scratch Org') {
steps{
create_scratch_org("${org}")
}
}
stage('Install Managed Package') {
when {
expression { (params.install_package == true) && (params.managed_package == true) }
}
steps {
install_package_for_org("${org}", params.version, params.namespace)
}
}
stage('Copy Config & Decrypt Secrets') {
steps{
echo "Copy Config & Decrypt Secrets"
}
}
}
}
stage("Running against Auto_org_2"){
environment{
auto_org_name = "auto_org_2"
auto_org_kexpr = "${params.kexpr2}"
}
steps{
echo "Running against Auto_org_2"
// Repeat stages from Auto_org_1
}
}
}
}
}
}
}
post {
always {
echo 'Post Execution'
script{remove_scratch_org("auto_org_1")}
script{remove_scratch_org("auto_org_2")}
}
failure {
echo "Tinkering Failed"
}
}
}
}
}
def create_scratch_org(org)
{
echo "create_scratch_org ${org}"
}
def remove_scratch_org(org)
{
echo "remove_scratch_org ${org}"
}
def setup_cci_org()
{
echo "Setting up cci org"
}
def install_package_for_org(org, version, namespace)
{
echo "install_package_for_org(org, version, namespace)"
}
What I would like to do is capture all the stages under stage("Running against Auto_org_1")
and put it in a method. I tried doing this by changing my code as follows –
#!groovy
@Library(<sharedLib>) _
def GIT_COMMIT_EMAIL
pipeline {
agent none
parameters {
...
}
options {
...
}
stages {
stage("Installing & Running Tests Stage")
{
agent {
docker {
...
}
}
stages {
stage('Checkout SCM') {
steps {
echo "Checkout"
}
}
stage("Setup and Run Tests in Parallel"){
stages{
stage('Setup CCI for Org') {
steps{
setup_cci_org()
}
}
stage("Create Scratch org and Run tests"){
parallel {
stage("Running against Auto_org_1"){
environment{
auto_org_name = "auto_org_1"
auto_org_kexpr = "${params.kexpr1}"
}
steps{
script{
all_steps("${auto_org_name}")
}
}
}
stage("Running against Auto_org_2"){
environment{
auto_org_name = "auto_org_2"
auto_org_kexpr = "${params.kexpr2}"
}
steps{
echo "Running against Auto_org_2"
// Repeat stages from Auto_org_1
}
}
}
}
}
}
}
post {
always {
echo 'Post Execution'
script{remove_scratch_org("auto_org_1")}
script{remove_scratch_org("auto_org_2")}
}
failure {
echo "Tinkering Failed"
}
}
}
}
}
def all_steps(org)
{
stage("All Steps stage"){
stages{
stage('Create Scratch Org') {
steps{
create_scratch_org("${org}")
}
}
stage('Install Managed Package') {
when {
expression { (params.install_package == true) && (params.managed_package == true) }
}
steps {
install_package_for_org("${org}", params.version, params.namespace)
}
}
stage('Copy Config & Decrypt Secrets') {
steps{
echo "Copy Config & Decrypt Secrets"
}
}
}
}
}
def create_scratch_org(org)
{
echo "create_scratch_org ${org}"
}
def remove_scratch_org(org)
{
echo "remove_scratch_org ${org}"
}
def setup_cci_org()
{
echo "Setting up cci org"
}
def install_package_for_org(org, version, namespace)
{
echo "install_package_for_org(org, version, namespace)"
}
But this throws an error java.lang.NoSuchMethodError: No such DSL method 'stages' found among steps
I have now spend enough time trying to figure out this, now hoping experts over here can guide me further
I know there is option to also move the code to shared library, but before that I would like this to work as a separate method. I assume if I put the body of method under vars folder and wrap it in a call
method same thing can be called as a script inside pipeline. Which is why local method is first thing I want to try as its faster to validate changes that way.