groovy Jenkinsfile -如何设置和使用同名变量?

lg40wkob  于 2022-11-01  发布在  Jenkins
关注(0)|答案(1)|浏览(200)

我认为这是一个变量范围问题。
我有一个Jenkins流水线,像这样有一个重复的switch-case语句。我的真实的用例有大约10个站点和很多不同的变量,几个Jenkins作业可以使用它,所以我想把这个逻辑拉到一个可重用的函数/类中。

pipeline {
  agent any
  parameters {
    choice (
      name: 'SOURCE_ENV',
      choices: [
        'site_01'
        'site_02'
      ],
      description: 'The source environment you want to copy to another server.',
    )
    choice (
      name: 'TARGET_ENV',
      choices: [
        'site_01'
        'site_02'
      ],
      description: 'The environment you want to refresh from another server.',
    )
  } // end params
  stages {
    stage('Initialization') {
      steps {
        script {
            switch (SOURCE_ENV) {
                case 'site_01':
                    def SOURCE_WEB_SERVER =     'site_01.someplace.org'
                    def SOURCE_DB_SERVER =      'site_01.db.someplace.org'
                    def SOURCE_DB_NAME =        'site_01_db'
                    def SOURCE_SITE_URL =       'https://some-spiffy-name.org'
                    break
                case 'site_02':
                    def SOURCE_WEB_SERVER =     'site_02.someplace.org'
                    def SOURCE_DB_SERVER =      'site_02.db.someplace.org'
                    def SOURCE_DB_NAME =        'site_02_db'
                    def SOURCE_SITE_URL =       'https://some-different-name.org'
                    break
                default:
                    error("ERROR: Unknown environment ${SOURCE_ENV}.")
                    break
            }
            switch (TARGET_ENV) {
                case 'site_01':
                    def TARGET_WEB_SERVER =     'site_01.someplace.org'
                    def TARGET_DB_SERVER =      'site_01.db.someplace.org'
                    def TARGET_DB_NAME =        'site_01_db'
                    def TARGET_SITE_URL =       'https://some-spiffy-name.org'
                    break
                case 'site_02':
                    def TARGET_WEB_SERVER =     'site_02.someplace.org'
                    def TARGET_DB_SERVER =      'site_02.db.someplace.org'
                    def TARGET_DB_NAME =        'site_02_db'
                    def TARGET_SITE_URL =       'https://some-different-name.org'
                    break
                default:
                    error("ERROR: Unknown environment ${TARGET_ENV}.")
                    break
            }
        } // end script
      } // end steps
    } // end stage

    stage('Do the Thing') {
      steps {
          script {
            echo "Do the thing we want to do."
          }
      } // end steps
    } // end stage
  } // end stages
} // end pipeline

我已经将逻辑移动到一个新文件中,它加载,但它的错误,并没有工作,我想要的。
摘自Jenkins档案:

...
    stage('Initialization') {
      steps {
        script {
          def source = load 'website_environment_ops/setEnvironments.groovy'
          source.setEnvironments(params.SOURCE_ENV)
          def target = load 'website_environment_ops/setEnvironments.groovy'
          target.setEnvironments(params.TARGET_ENV)

          echo "SOURCE WEB_SERVER:  ${source.WEB_SERVER}\n"
          echo "TARGET WEB_SERVER:  ${target.WEB_SERVER}\n"
        } // end script
      } // end steps
    } // end stage
...

setEnvironments.groovy文件。

def setEnvironments(ENV) {
 switch (ENV) {
  case 'site_01':
   def WEB_SERVER =  'site_01.someplace.org'
   def DB_SERVER =  'site_01.db.someplace.org'
   def DB_NAME =    'site_01_db'
   def SITE_URL =   'https://some-spiffy-name.org'
   break
  case 'site_02':
   def WEB_SERVER =  'site_02.someplace.org'
   def DB_SERVER =  'site_02.db.someplace.org'
   def DB_NAME =    'site_02_db'
   def SITE_URL =   'https://some-different-name.org'
   break
  default:
   error("ERROR: Unknown environment.")
   break
 }
}
return this

我收到如下错误:'脚本1.groovy:50:当前作用域已包含名为WEB_SERVER'的变量
我知道这是因为我的变量实际上并没有像我希望的那样被划分到“source”和“target”中,而是被加载到了同一个作用域中。
但是,我不知道如何将作用域为不同实体的同名变量放在一个Jenkinsfile文件中使用,或者,我不知道如何动态命名这些变量,或者,我不知道如何使用setEnvironments.groovy文件这样的解决方案来减少代码中的重复。
我希望能够调用source.WEB_SERVERtarget.WEB_SERVER这样的变量,或者使用setEnvironments.groovy动态命名它的变量,例如SOURCE_WEB_SERVERTARGET_WEB_SERVER
有人有什么想法吗?谢谢

izkcnapc

izkcnapc1#

试着像下面这样重新构造你的setEnvironments.groovy脚本。基本上,你不应该在每次设置变量时都声明它们。

def WEB_SERVER
def DB_SERVER
def DB_NAME
def SITE_URL

def setEnvironments(ENV) {
   switch (ENV) {
   case 'site_01':
      WEB_SERVER =  'site_01.someplace.org'
      DB_SERVER =  'site_01.db.someplace.org'
      DB_NAME =    'site_01_db'
      SITE_URL =   'https://some-spiffy-name.org'
   case 'site_02':
      WEB_SERVER =  'site_02.someplace.org'
      DB_SERVER =  'site_02.db.someplace.org'
      DB_NAME =    'site_02_db'
      SITE_URL =   'https://some-different-name.org'
   default:
      error("ERROR: Unknown environment.")
   }
}

return this

然后像下面这样使用它。

def params = load 'website_environment_ops/setEnvironments.groovy'
params.setEnvironments(params.SOURCE_ENV)
echo "$params.WEB_SERVER"

params.setEnvironments(params.TARGET_ENV)
echo "$params.WEB_SERVER"

顺便说一句,最好考虑将管道迁移到Shared Library。这将允许您分离出可重用的代码,并将它们作为适当的Groovy代码进行管理。下面是一个示例(这有点复杂,但可以给予您一个思路),满足您管理属性的需求。请检查此处和here

更新:返回属性Map

如果你真的想同时保留目标属性和源属性,你可以从你的函数中返回一个属性Map。

def setEnvironments(ENV) {
    def propMap = [:]
    switch (ENV) {
      case 'site_01':
        propMap["WEB_SERVER"]   =  'site_01.someplace.org'
        propMap["DB_SERVER"]    =  'site_01.db.someplace.org'
        propMap["DB_NAME"]      =  'site_01_db'
        propMap["SITE_URL"]     =  'https://some-spiffy-name.org'
      case 'site_02':
        propMap["WEB_SERVER"]  =  'site_02.someplace.org'
        propMap["DB_SERVER"]   =  'site_02.db.someplace.org'
        propMap["DB_NAME"]     =  'site_02_db'
        propMap["SITE_URL"]   =  'https://some-different-name.org'
      default:
         error("ERROR: Unknown environment.")
    }
    return propMap
 }

在管道中

def script = load 'website_environment_ops/setEnvironments.groovy'
def source = script.setEnvironments(params.SOURCE_ENV)

def target = script.setEnvironments(params.TARGET_ENV)

echo source["WEB_SERVER"]
echo target["WEB_SERVER"]
echo source["DB_SERVER"]
echo target["DB_SERVER"]

相关问题