Jenkinsfile 和 Python virtualenv

新手上路,请多包涵

我正在尝试设置一个使用闪亮的新 Jenkins 管道的项目,更具体地说是一个多分支项目。

我在测试分支中创建了一个 Jenkinsfile ,如下所示:

 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'

看起来它正在尝试在全局环境中而不是在 virtualenv 中更新 pip,并且看起来每个 sh 步骤都在其自己的上下文中,如何让它们在相同的上下文中执行?

原文由 James Lin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 894
2 个回答

你试图做的是行不通的。每次调用 sh 命令时,jenkins 都会创建一个新的 shell。

这意味着如果您在 .env/bin/activate 中使用 sh 它将仅在该 shell 会话中获取。结果是,在新的 sh 命令中,您必须再次获取文件源(如果仔细查看控制台输出,您会发现 Jenkins 实际上会在每次运行命令时创建临时 shell 文件.

因此,您应该在每个 shell 命令的开头获取 .env/bin/activate 文件(您可以对多行字符串使用三重引号),如下所示

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
"""

原文由 Rik 发布,翻译遵循 CC BY-SA 4.0 许可协议

就像 Rik 发布的那样,virtualenvs 在 Jenkins 管道环境中不能很好地工作,因为为每个命令创建了一个新的 shell。

我创建了一个插件,可以减轻这个过程的痛苦,可以在这里找到: https ://wiki.jenkins.io/display/JENKINS/Pyenv+Pipeline+Plugin。它本质上只是以一种在运行命令之前激活 virtualenv 的方式包装每个调用。这本身就很棘手,因为一些内联运行多个命令的方法被 Jenkins 分成两个单独的命令,导致激活的 virtualenv 不再适用。

原文由 cstarner 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题