我正在尝试设置一个使用闪亮的新Jenkins管道的项目,更具体地说是一个多分支项目。
我在测试分支中创建了一个Jenkins文件,如下所示:
node {
stage 'Preparing VirtualEnv'
if (!fileExists('.env')){
echo 'Creating virtualenv ...'
sh 'virtualenv --no-site-packages .env'
}
sh '. .env/bin/activate'
sh 'ls -all'
if (fileExists('requirements/preinstall.txt')){
sh 'pip install -r requirements/preinstall.txt'
}
sh 'pip install -r requirements/test.txt'
stage 'Unittests'
sh './manage.py test --noinput'
}
值得注意的是,preinstall.txt将更新pip
我收到如下错误:
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/pip'
看起来它正在尝试更新全局环境中的pip而不是内部virtualenv,并且看起来每个sh
步骤都在其自己的上下文中,如何使它们在相同的上下文中执行?
答案 0 :(得分:15)
你要做的事情是行不通的。每次调用sh
命令时,jenkins都会创建一个新shell。
这意味着如果您在.env/bin/activate
中使用sh
,那么它将只是该shell会话中的来源。结果是,在新的sh
命令中,您必须再次获取文件(如果仔细查看控制台输出,您将看到Jenkins实际上每次运行comman时都会创建临时shell文件。 / p>
所以你应该在每个shell命令的开头找到.env/bin/activate
文件(你可以对多行字符串使用三个qoutes),就像这样
if (fileExists('requirements/preinstall.txt')) {
sh """
. .env/bin/activate
pip install -r requirements/preinstall.txt
"""
}
...
sh """
. .env/bin/activate
pip install -r requirements/test.txt
"""
}
stage("Unittests") {
sh """
. .env/bin/activate
./manage.py test --noinput
"""
}
或在一个shell中运行它
sh """
. .env/bin/activate
if [[ -f requirements/preinstall.txt ]]; then
pip install -r requirements/preinstall.txt
fi
pip install -r requirements/test.txt
./manage.py test --noinput
"""
答案 1 :(得分:4)
就像Rik发布的那样,virtualenvs在Jenkins管道环境中不能很好地工作,因为为每个命令创建了一个新的shell。
我创建了一个插件,让这个过程不那么痛苦,可以在这里找到:https://wiki.jenkins.io/display/JENKINS/Pyenv+Pipeline+Plugin。它基本上只是以一种在运行命令之前激活virtualenv的方式包装每个调用。这本身就很棘手,因为一些运行多个内联命令的方法被Jenkins分成两个单独的命令,导致激活的virtualenv不再适用。
答案 2 :(得分:-1)
我是詹金斯文件的新手。以下是我如何解决虚拟环境问题的方法。 (我正在运行Python3,Jenkins 2.73.1)
警告:为了清楚起见,我并不是说这是一个解决问题的好方法,我也没有足够的测试来支持这种方法,但今天对我有用的是:我一直在玩绕过venv'激活'通过直接调用虚拟环境的python解释器。所以而不是:
source ~/venv/bin/activate
可以使用:
~/venv/bin/python3 my_script.py
我通过shell的rc文件(在我的情况下,~/.bashrc
)将路径传递给我的虚拟环境python解释器。理论上,Jenkins调用的每个shell都应该读取此资源文件。实际上,我必须在更改shell资源文件后重新启动Jenkins。
HOME_DIR=~
export VENV_PATH="$HOME_DIR/venvs/my_venv"
export PYTHON_INTERPRETER="${VENV_PATH}/bin/python3"
我的Jenkinsfile看起来与此相似:
pipeline {
agent {
label 'my_slave'
}
stages {
stage('Stage1') {
steps {
// sh 'echo $PYTHON_INTERPRETER'
// sh 'env | sort'
sh "$PYTHON_INTERPRETER my_script.py "
}
}
}
}
因此,当管道运行时,sh设置了$ PYTHON_INTERPRETER环境值。
注意这种方法的一个缺点是,现在Jenkins文件不包含正确运行脚本的所有必要信息。希望这会让你开始。