使用 virtualenv 在 Jenkins 中为每个作业设置环境

使用 virtualenv 在 Jenkins 中为每个作业设置环境

我正在尝试使用virtualenv编程方式管理 Jenkins 服务器上每个作业的 Python 环境,通过以下方式实现共享库扩展以根据每个作业激活环境。例如:

/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

我试过使用这个答案让 Jenkins 使用登录 shell,但每次sh调用时仍会重新加载环境。

我也看到了这个答案这就需要sh在管道中每次使用某个步骤时粘贴额外的文本——这并不理想。

有没有一种好的方法可以让环境在sh命令之间保持不变?或者,有没有更好的方法来实现每个作业的环境virtualenv?感谢所有的帮助/建议!

答案1

我遇到了同样的问题。在与一些资深的 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,所以最终没有真正好的或干净的方法来做到这一点。

可能有更好的方法将虚拟环境与 Jenkins 结合使用,但我从未编写过在虚拟环境中运行任务的 Jenkins 作业,所以我不能说。这个插件, 但另一个 stackoverflow 答案表明我在这个答案中给出的方法是使用 Jenkins 中的虚拟环境的首选方法。

相关内容