Файл конвейера Jenkins - Передача переменных Jenkinsfile в дальнейшие команды
Выпуск:
Передав переменную, объявленную в Jenkinsfile, sh
Команда ssh выполняет и выполняет на удаленном хосте, содержимое переменной не сохраняется на удаленном хосте.
Встроенные переменные Jenkins прекрасно сохраняются как локально, так и на удаленном хосте. Переменная, которую я определил, прекрасно работает локально, но не переводится на удаленный хост.
Хотя эта проблема относится к Docker, на самом деле она на 100% основана на конвейере Jenkins, поскольку может применяться к любому примеру с Docker или без него.
Фон:
Я пытаюсь динамически создать имя изображения на основе текущего тега сборки и поместить это имя в переменную.
Затем я передаю эту переменную в sh
шаг, который удаленно подключается к хосту Docker и запускает шаг сборки с определенным именем.
Фрагмент применимых частей Jenkinsfile...
// The below stage just echo's out some stuff into a file dockerimgname.jenkins.out
stage ('Construct Img name') {
sh '''echo ${BUILD_TAG} | awk '{print tolower($0)}' | sed 's/jenkins-//' > dockerimgname.jenkins.out'''
}
// This stage reads that file from previous stage and puts the value into variable.
// The variable is echo'd locally which works perfectly. Then ssh is called to execute command on remote host. That's where the variable value doesn't work.
stage ('Build Target Container') {
def jobBaseName = readFile 'dockerimgname.jenkins.out'
echo "${jobBaseName}"
sh 'ssh -i ~/ssh_keys/key.key user@somehost "cd /dockerdata/build/${BUILD_TAG} && docker build -t localrepo/${jobBaseName}:${BUILD_NUMBER} ."'
}
Обычно я предполагаю, что у него нет переменных, поскольку это удаленный хост... Однако странно, что ${BUILD_NUMBER}
а также ${BUILD_TAG}
перевести и нормально работать на удаленном хосте. Почему не ${jobBaseName}
?? (выходит пустым / пустым на удаленном хосте).
1 ответ
Поскольку не гарантируется, что ваши отдельные этапы будут выполняться на одном и том же узле-исполнителе (если только этапы не объединены в одном node
блок), использование файлов для обмена информацией между этапами будет ненадежным. Вместо этого используйте переменные:
def jobBaseName
stage ('Construct Img name') {
jobBaseName = sh(
script: "echo ${BUILD_TAG} | awk '{print tolower($0)}' | sed 's/jenkins-//'",
returnStdout: true,
)
}
stage ('Build Target Container') {
sh "ssh -i ~/ssh_keys/key.key user@somehost 'cd /dockerdata/build/${BUILD_TAG} && docker build -t localrepo/${jobBaseName}:${BUILD_NUMBER} .'"
}
Кстати, я бы также предложил использовать sshAgent
и встроенное хранилище учетных данных Jenkins для управления ключами SSH вместо ручной передачи в -i
флаг SSH.