Bash

Jenkins 中使用 virtualenv 的每個作業環境

  • February 28, 2018

我正在嘗試使用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 的首選方法。

引用自:https://serverfault.com/questions/897623