1

I have a project which has multiple build pipelines to allow for different types of builds against it (no, I don't have the ability to make one build out of it; that is outside my control).

Each of these pipelines is represented by a Jenkinsfile in the project repo, and each one must use the same build agent label (they need to share other pieces of configuration as well, but it's the build agent label which is the current problem). I'm trying to put the label into some sort of a configuration file in the project repo, so that all the Jenkinsfiles can read it.

I expected this to be simple, as you don't need this config data until you have already checked out a copy of the sources to read the Jenkinsfile. As far as I can tell, it is impossible.

It seems to me that a Jenkinsfile cannot read files from SCM until the project has done its SCM step. However, that's too late: the argument to agent{label} is read before any stages get run.

Here's a minimal case:

final def config
pipeline {
    agent none
    stages {
        stage('Configure') {
            agent {
                label 'master'
            }
            steps {
                checkout scm // we don't need all the submodules here
                echo "Reading configuration JSON"
                script { config = readJSON file: 'buildjobs/buildjob-config.json' }
                echo "Read configuration JSON"
            }
        }
        stage('Build and Deploy') {
            agent {
                label config.agent_label
            }
            steps {
                echo 'Got into Stage 2'
            }
        }
    }
}

When I run this, I get: java.lang.NullPointerException: Cannot get property 'agent_label' on null object I don't get either of the echoes from the 'Configure' stage.

If I change the label for the 'Build and Deploy' stage to 'master', the build succeeds and prints out all three echo statements.

Is there any way to read a file from the Git workspace before the agent labels need to be set?

  • What happens if you just run first stage (remove second stage altogether) and echo config.agent_label. Does it output correctly ? – ben5556 Oct 15 '18 at 18:55

1 Answers1

0

Please see https://stackoverflow.com/a/52807254/7983309. I think you are running into this issue. label is unable to resolve config.agent_label to its updated value. Whatever is set in the first line is being sent to your second stage.

EDIT1:

env.agentName = ''
pipeline {
    agent none
    stages {
        stage('Configure') {
            agent {
                label 'master'
            }
            steps {
                script {
                    env.agentName = 'slave'
                    echo env.agentName
                }    
            }
        }
        stage('Finish') {
            steps {
                node (agentName as String) { println env.agentName }
                script {
                    echo agentName
                }
            }
        }
    }
}

Source - In a declarative jenkins pipeline - can I set the agent label dynamically?

ben5556
  • 2,915
  • 2
  • 11
  • 16
  • Not the answer that I was looking for, but it looks like the right answer. In other words, it seems impossible to do what I'm trying to do. Thank you. – Robert Mandeville Oct 16 '18 at 16:11
  • Found interesting solution on another thread. Tested and it works. Will post the script in the answer section above as I'm unable to format it here. See if you can use that in your use case – ben5556 Oct 16 '18 at 19:56