Ответ 1
Чтобы узнать, как это работает, используйте объект GString
для выполнения println
и одновременно возвращайте переменную для имени агента. Вы можете видеть на выходе, что эта строка хорошо оценивается перед любым другим кодом конвейера.
agentName = "Windows"
agentLabel = "${println 'Right Now the Agent Name is ' + agentName; return agentName}"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
agentName = "Linux"
}
}
}
stage('Checking') {
steps {
script {
println agentLabel
println agentName
}
}
}
stage('Final') {
agent { label agentLabel }
steps {
script {
println agentLabel
println agentName
}
}
}
}
}
Консольный вывод (обратите внимание, что на самом деле у меня нет узла в этом экземпляре с именем Windows, поэтому я прервал его после того, как он не смог его найти):
Started by user Admin
[Pipeline] echo
Right Now the Agent Name is Windows
[Pipeline] stage
[Pipeline] { (Prep)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Checking)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Windows
[Pipeline] echo
Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Final)
[Pipeline] node
Still waiting to schedule task
There are no nodes with the label ‘Windows
Aborted by Admin
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
ERROR: Queue task was cancelled
Finished: ABORTED
Обратите внимание, как строка Right Now the Agent Name is Windows
появляется очень рано на выходе. Это объясняет, почему ваше значение равно null. Этот оператор оценивается задолго до того, как ваш скрипт изменяет переменную.
Я могу попытаться использовать ленивый GString
чтобы получить переменную позже.
agentLabel = "${-> println 'Right Now the Agent Name is ' + agentName; return agentName}"
К сожалению, это вызывает ошибку, потому что ожидает тип String. По-видимому, он может принуждать нелазную GString к String самостоятельно, но не к ленивой версии. Поэтому, когда я принуждаю принуждение к String, конечно, он оценивает переменную в это время (что опять же, до того, как фактически выполняется код конвейера).
agent { label agentLabel as String }
Вы можете решить проблему, обратившись к методу распределения старого узла:
agentName = "Windows"
agentLabel = "${-> println 'Right Now the Agent Name is ' + agentName; return agentName}"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
agentName = "Linux"
}
}
}
stage('Checking') {
steps {
script {
println agentLabel
println agentName
}
}
}
stage('Final') {
steps {
node( agentLabel as String ) { // Evaluate the node label later
echo "TEST"
}
script {
println agentLabel
println agentName
}
}
}
}
}
Вы можете увидеть на этом консольном выходе, что теперь он правильно находит узел Linux и заканчивает конвейер. Ранняя оценка while agentName == Windows никогда не происходит:
Started by user Admin
[Pipeline] stage
[Pipeline] { (Prep)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Checking)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Right Now the Agent Name is Linux
[Pipeline] echo
Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Final)
[Pipeline] echo
Right Now the Agent Name is Linux
[Pipeline] node
Running on Slave 1 in /home/jenkinsslave/jenkins/workspace/test
[Pipeline] {
[Pipeline] echo
TEST
[Pipeline] }
[Pipeline] // node
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Right Now the Agent Name is Linux
[Pipeline] echo
Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS
Это, вероятно, будет работать без ленивого GString
и типа принуждения позже, но я не пробовал это.