詹金斯在文件中插入环境变量

时间:2020-03-10 20:43:20

标签: shell jenkins

我有一个.env文件,其中包含以下数据

API_URL=${API_URL}
API_KEY=${API_KEY}
API_SECRET=${API_SECRET}

在Jenkins中设置环境变量并将其传递到管道是显而易见的。但是尚不清楚如何用Jenkins环境变量中的值替换.env文件中的$ {API_URL},$ {API_KEY}和$ {API_SECRET}?另外,如何遍历所有Jenkins变量?

2 个答案:

答案 0 :(得分:1)

这基本上需要两个步骤:

  1. 获取所有环境变量
  2. 替换模板(.env)文件中环境变量的值

让我们从#2开始,因为它决定了#1必须产生哪种数据。

2。替换模板中的变量

我们可以将Groovy的SimpleTemplateEngine用于此任务。

def result = new SimpleTemplateEngine().createTemplate( templateStr ).make( dataMap )

此处templateStr是模板字符串(.env文件的内容),dataMap必须是由字符串键和值(环境变量的实际值)组成的Map 。获取模板字符串很简单(使用Jenkins readFile步骤),将环境变量读入Map会稍微复杂一些。

1。将环境变量读取到地图中

我写了“ 稍微更多”,因为Groovy的天赋使这项任务也很容易。

@Chris has already shown如何将环境变量读取为字符串。我们需要做的是将该字符串分割成几行,首先分成几行,然后将每一行分成键和值。幸运的是,Groovy提供了String类的成员函数splitEachLine,可以通过一次调用完成两个步骤!
有一点警告,因为splitEachLine是在Jenkins管道上下文中表现不佳的功能之一-它只会返回第一行。将关键代码移动到带有@NonCPS注释的单独函数中可以解决此问题。

@NonCPS
Map<String,String> envStrToMap( String envStr ) {
    def envMap = [:]
    envStr.splitEachLine('=') {
        envMap[it[0]] = it[1]
    } 
    return envMap
}

最后

现在,我们拥有让詹金斯为我们烹饪美味的模板汤的所有原料!

这里是完整的管道演示。它使用脚本样式,但也应该易于使用声明式样式。只需将node替换为script块。

import groovy.text.SimpleTemplateEngine     

node {
    // TODO: Replace the hardcoded string with: 
    // def tmp = readFile file: 'yourfile.env'
    def tmp = '''\
API_URL=${API_URL}
API_KEY=${API_KEY}
API_SECRET=${API_SECRET}'''
    
    withEnv(['API_URL=http://someurl', 'API_KEY=123', 'API_SECRET=456']) {    
    
        def envMap = getEnvMap()
        echo "envMap:\n$envMap"
        
        def tmpResolved = new SimpleTemplateEngine().createTemplate( tmp ).make( envMap )
  
        writeFile file: 'test.env', text: tmpResolved.toString()

        // Just for demo, to let me see the result
        archiveArtifacts artifacts: 'test.env' 
    }
}

// Read all environment variables into a map.
// Here, @NonCPS must NOT be used, because we are calling a Jenkins step.
Map<String,String> getEnvMap() {
    def envStr = sh(script: 'env', returnStdout: true)
    return envStrToMap( envStr )
}

// Split a multiline string, where each line consists of key and value separated by '='.
// It is critical to use @NonCPS to make splitEachLine() work!
@NonCPS
Map<String,String> envStrToMap( String envStr ) {
    def envMap = [:]
    envStr.splitEachLine('=') {
        envMap[it[0]] = it[1]
    } 
    return envMap
}

管道使用以下内容创建工件“ test.env”:

API_URL=http://someurl
API_KEY=123
API_SECRET=456

答案 1 :(得分:0)

您可以通过在脚本管道中执行简单的shell来访问变量:

def variables = sh(script: 'env|sort', returnStdout: true)

然后在Groovy中以编程方式将其转换为列表并使用每个循环进行迭代。

根据替换变量,如果您没有使用任何可以访问env变量的解决方案,则可以使用简单的文本操作,例如对该文件执行sed。