簡體   English   中英

使用環境變量 Jenkins Pipeline 加載文件

[英]Load file with environment variables Jenkins Pipeline

我正在做一個簡單的管道:

構建 -> 分期 -> 生產

我需要分期和生產不同的環境變量,所以我試圖變量。

sh 'source $JENKINS_HOME/.envvars/stacktest-staging.sh' 

但它返回未找到

[Stack Test] Running shell script
+ source /var/jenkins_home/.envvars/stacktest-staging.sh
/var/jenkins_home/workspace/Stack Test@tmp/durable-bcbe1515/script.sh: 2: /var/jenkins_home/workspace/Stack Test@tmp/durable-bcbe1515/script.sh: source: not found

路徑是正確的,因為我在通過 ssh 登錄時運行相同的命令,並且它工作正常。

這是管道的想法:

node {
    stage name: 'Build'
    // git and gradle build OK
    echo 'My build stage'

    stage name: 'Staging'
    sh 'source $JENKINS_HOME/.envvars/stacktest-staging.sh' // PROBLEM HERE
    echo '$DB_URL' // Expects http://production_url/my_db
    sh 'gradle flywayMigrate' // To staging
    input message: "Does Staging server look good?"    

    stage name: 'Production'
    sh 'source $JENKINS_HOME/.envvars/stacktest-production.sh'
    echo '$DB_URL' // Expects http://production_url/my_db
    sh 'gradle flywayMigrate' // To production
    sh './deploy.sh'
}

我該怎么辦?

  • 我在考慮不使用管道(但我將無法使用我的 Jenkinsfile)。
  • 或者使用 EnvInject 插件為舞台和制作制作不同的工作(但我失去了舞台視圖)
  • 或者 make withEnv (但是代碼變大了,因為今天我正在使用 12 個環境變量)

從文件加載環境變量的一種方法是加載 Groovy 文件。

例如:

  1. 假設您在“$JENKINS_HOME/.envvars”中有一個名為“stacktest-staging.groovy”的 groovy 文件。
  2. 在此文件中,您定義了要加載的 2 個環境變量

    env.DB_URL="hello" env.DB_URL2="hello2"
  3. 然后你可以加載它使用

    load "$JENKINS_HOME/.envvars/stacktest-staging.groovy"
  4. 然后您可以在后續的 echo/shell 步驟中使用它們。

例如,這是一個簡短的管道腳本:

node {
   load "$JENKINS_HOME/.envvars/stacktest-staging.groovy"
   echo "${env.DB_URL}"
   echo "${env.DB_URL2}"
}

從評論到接受的答案

不要使用全局 'env' 而是使用 'withEnv' 構造,例如參見:問題 #9:不要在十大最佳實踐 jenkins 管道插件中使用全局 env 設置 env 變量

在下面的例子中:VAR1 是一個普通的 java 字符串(沒有 groovy 變量擴展),VAR2 是一個 groovy 字符串(所以變量 'someGroovyVar' 被擴展)。

傳遞的腳本是一個普通的 java 字符串,因此 $VAR1 和 $VAR2 被逐字傳遞給 shell,並且回聲正在訪問環境變量 VAR1 和 VAR2。

stage('build') {
    def someGroovyVar = 'Hello world'
    withEnv(['VAR1=VALUE ONE',
             "VAR2=${someGroovyVar}"
            ]) {
        def result = sh(script: 'echo $VAR1; echo $VAR2', returnStdout: true)
        echo result
    }
}

對於秘密/密碼,您可以使用憑據綁定插件

示例:

注意:CREDENTIALS_ID1 是 Jenkins 設置中注冊的用戶名/密碼秘密。

stage('Push') {
    withCredentials([usernamePassword(
                         credentialsId: 'CREDENTIALS_ID1',
                         passwordVariable: 'PASSWORD',
                         usernameVariable: 'USER')]) {
        echo "User name: $USER"
        echo "Password:  $PASSWORD"
    }
}

jenkisn 控制台日志輸出隱藏了真實值:

[Pipeline] echo
User name: ****
[Pipeline] echo
Password:  ****

Jenkins 和憑證是個大問題,大概看: 憑證插件

為了完整性:大多數時候,我們需要環境變量中的秘密,因為我們在 shell 腳本中使用它們,因此我們將 withCredentials 和 withEnv 組合在一起,如下所示:

stage('Push') {
    withCredentials([usernamePassword(
                         credentialsId: 'CREDENTIALS_ID1',
                         passwordVariable: 'PASSWORD',
                         usernameVariable: 'USER')]) {
        withEnv(["ENV_USERNAME=${USER}",
                 "ENV_PASSWORD=${PASSWORD}"
            ]) {
                def result = sh(script: 'echo $ENV_USERNAME', returnStdout: true)
                echo result

        }
    }
}

另一種解決此安裝“Pipeline Utility Steps”插件的方法,該插件為我們提供了 readProperties 方法(有關參考,請轉到鏈接https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#pipeline-utility-步驟) 在示例中,我們可以看到它們將鍵存儲到數組中並使用鍵來檢索值。 但在這種情況下,如果我們稍后將任何變量添加到屬性文件中,該變量也需要添加到 Jenkins 文件的數組中,那么在生產中的問題將是這樣。 為了擺脫這種緊耦合,我們可以這樣編寫代碼,以便 Jenkins 構建環境可以自動獲取有關當前出現在屬性文件中的所有現有鍵的信息。 這是參考的示例

def loadEnvironmentVariables(path){
    def props = readProperties  file: path
    keys= props.keySet()
    for(key in keys) {
        value = props["${key}"]
        env."${key}" = "${value}"
    }
} 

客戶端代碼看起來像

path = '\\ABS_Output\\EnvVars\\pic_env_vars.properties'
loadEnvironmentVariables(path)

使用聲明式管道,您可以在一行中完成(根據您的值更改path ):

script {
  readProperties(file: path).each {key, value -> env[key] = value }
}

使用 withEnv() 從由新行拆分的文件中傳遞環境變量並轉換為 List:

writeFile file: 'version.txt', text: 'version=6.22.0'
withEnv(readFile('version.txt').split('\n') as List) {
    sh "echo ${version}"
}

如果您使用的是 Jenkins 2.0,您可以加載屬性文件(其中包含所有必需的環境變量及其相應的值)並自動讀取其中列出的所有環境變量並將其注入到 Jenkins 提供的 env 實體中。

這是執行上述操作的方法。

def loadProperties(path) {
    properties = new Properties()
    File propertiesFile = new File(path)
    properties.load(propertiesFile.newDataInputStream())
    Set<Object> keys = properties.keySet();
    for(Object k:keys){
    String key = (String)k;
    String value =(String) properties.getProperty(key)
    env."${key}" = "${value}"
    }
}

要調用此方法,我們需要將屬性文件的路徑作為字符串變量傳遞例如,在我們使用 groovy 腳本的 Jenkins 文件中,我們可以像這樣調用

path = "${workspace}/pic_env_vars.properties"
loadProperties(path)

如果您有任何疑問,請問我

另一種解決方案是使用自定義方法而不允許額外的權限,例如new Properties()在允許之前導致此錯誤:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.util.Properties

或添加額外的插件方法,例如readProperties

這是一種以這種格式讀取名為env_vars的簡單文件的方法:

FOO=bar
FOO2=bar
pipeline {
<... skipped lines ...>
    script {
        loadEnvironmentVariablesFromFile("env_vars")

        echo "show time! ${BAR} ${BAR2}"
    }
<... skipped lines ...>
}

private void loadEnvironmentVariablesFromFile(String path) {
    def file = readFile(path)
    file.split('\n').each { envLine ->
        def (key, value) = envLine.tokenize('=')
        env."${key}" = "${value}"
    }
}

這是外部化環境變量並在 Jenkins 管道執行中加載它們的完整示例。 管道以聲明式編寫。

stage('Reading environment variable defined in groovy file') {
            steps {
                script {
                    load "./pipeline/basics/extenvvariable/env.groovy"
                    echo "${env.env_var1}"
                    echo "${env.env_var2}"
                }
            }
        }

完整代碼示例: https : //github.com/dhruv-bansal/jenkins-pipeline-exploration/blob/master/pipeline/basics/extenvvariable/Jenkinsfile

其中變量是從僅與管道代碼一起放置的 groovy 文件加載的。 https://github.com/dhruv-bansal/jenkins-pipeline-exploration/blob/master/pipeline/basics/extenvvariable/env.groovy

當您創建可跨團隊使用的通用管道時,此模式非常方便。 您可以將此類 groovy 文件中的因變量外部化,每個團隊可以根據其生態系統定義其值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM