Файл конвейера 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.

Другие вопросы по тегам