Я пытаюсь использовать 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.