I'm trying to use virtualenv
to programmatically manage Python environments for each job on a Jenkins server, implemented via a Shared Library extension to activate environments on a per job basis. E.g.:
/vars/activateEnvironment.groovy
:
def call(String env = "/usr/local/etc/environments/jenkins-$JOB_NAME") {
sh """
mkdir ${env}
virtualenv ${env}
source ${env}/bin/activate
"""
}
Pipeline script, in which the virtualenv-scripts
repository contains the above file:
@Library('virtualenv-scripts') _
pipeline {
agent any
stages {
stage("Test") {
steps {
activateEnvironment()
sh 'which pip'
sh 'echo \$PATH'
}
}
}
}
Running this pipeline script, I get the following output:
[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
I've tried using this answer to make Jenkins use a login shell, but that still reloads the environment with every sh
call.
I also saw this answer which would require pasting extra text every time a sh
step is used in a Pipeline -- not ideal.
Is there a good way to have environment persist between sh
commands? Alternately, is there a better way to achieve per-job environments with virtualenv
? Thanks for all help/suggestions!