Bash
Jenkins 中使用 virtualenv 的每個作業環境
我正在嘗試使用
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
?感謝所有幫助/建議!
我遇到過同樣的問題。在與一些資深的 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
,因此最終沒有真正好的或乾淨的方法來做到這一點。可能有更好的方法將 virtualenvs 與 Jenkins 一起使用,但我從未編寫過在 virtualenv 中執行任務的 Jenkins 作業,所以我不能說。有這個外掛,但另一個 stackoverflow 答案表明我在這個答案中給出的方法是在 Jenkins 中使用 virtualenvs 的首選方法。