Назад | Перейти на главную страницу

Рабочие среды в Jenkins с virtualenv

Я пытаюсь использовать virtualenv для программного управления средами Python для каждого задания на сервере Jenkins, реализованного через Общая библиотека расширение для активации сред для каждой работы. Например.:

/vars/activateEnvironment.groovy:

def call(String env = "/usr/local/etc/environments/jenkins-$JOB_NAME") {

    sh """
    mkdir ${env}
    virtualenv ${env}
    source ${env}/bin/activate
    """
}

Скрипт конвейера, в котором virtualenv-scripts репозиторий содержит указанный выше файл:

@Library('virtualenv-scripts') _

pipeline {
    agent any
    stages {
        stage("Test") {
            steps {
                activateEnvironment()
                sh 'which pip'
                sh 'echo \$PATH'
            }
        }
    }
}

Запустив этот сценарий конвейера, я получаю следующий вывод:

[Pipeline] sh
[example-pipeline] Running shell script
+ echo /sbin:/usr/sbin:/bin:/usr/bin
/sbin:/usr/sbin:/bin:/usr/bin
[Pipeline] sh
[example-pipeline] Running shell script
+ which pip
/bin/pip

Я пробовал использовать этот ответ чтобы заставить Дженкинса использовать оболочку входа в систему, но это по-прежнему перезагружает среду с каждым sh вызов.

Я также видел этот ответ что потребовало бы вставки дополнительного текста каждый раз, когда sh step используется в конвейере - не идеально.

Есть ли хороший способ сохранить среду между sh команды? В качестве альтернативы, есть ли лучший способ создать среду для каждой работы с virtualenv? Спасибо за помощь / предложения!

Я была такая же проблема. Поговорив с некоторыми опытными администраторами Jenkins, я пришел к следующему решению:

def runCommandInMyEnvironment(cmd) {
  sh "setup_environment_command; source ./some/file; ${cmd}"
}

pipeline {
  agent any
  stages {
    stage("My Stage") {
      steps {
        runCommandInMyEnvironment('first_command')
        runCommandInMyEnvironment('second_command')
        // and so on
      }
    }
  }
}

Это некрасиво и может немного испортить вывод консоли, но это также самый надежный способ сделать это.

Другой подход состоял бы в том, чтобы проанализировать вывод некоторой команды и разбить его на кучу переменных среды, а затем передать их в withEnv блокировать, но это может быть очень хитрый и ненадежный подход.

В любом случае, как вы упоминали, Jenkins не поддерживает постоянные среды без withEnv, так что, в конечном счете, нет никакого хорошего или чистого способа сделать это.

Возможно, есть лучший способ использовать virtualenvs с Jenkins, но я никогда не писал задание Jenkins, которое запускает задачи в virtualenv, поэтому я не могу сказать. Там есть этот плагин, но другой ответ stackoverflow предполагает, что подход, который я дал в этом ответе, является предпочтительным методом для работы с virtualenvs в Jenkins.