光沢のある新しい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内ではなくグローバルenvでpipを更新しようとしているように見え、各sh
ステップが独自のコンテキスト上にあるように見えますが、同じコンテキスト内で実行するにはどうすればよいですか?
あなたがしようとしていることは機能しません。 sh
コマンドを呼び出すたびに、jenkinsは新しいシェルを作成します。
これは、.env/bin/activate
内のsh
は、そのシェルセッションのソースのみになります。その結果、新しいsh
コマンドでファイルを再度ソースする必要があります(コンソール出力を詳しく見ると、Jenkinsがコマンドを実行するたびに一時的なシェルファイルを実際に作成することがわかります。
したがって、.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
"""
}
またはすべてを1つのシェルで実行します
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が投稿したように、virtualenvはJenkins Pipeline Environment内ではうまく機能しません。これは、コマンドごとに新しいシェルが作成されるためです。
このプロセスの苦痛を少し軽減するプラグインを作成しました。このプラグインは https://wiki.jenkins.io/display/JENKINS/Pyenv+Pipeline+Plugin にあります。基本的には、コマンドを実行する前にvirtualenvをアクティブにする方法で各呼び出しをラップします。複数のコマンドをインラインで実行するいくつかの方法がJenkinsによって2つの別個のコマンドに分割され、アクティブ化されたvirtualenvが適用されなくなるため、これ自体は注意が必要です。