Дженкинс: получить переменные окружения в теле глобальной функции - PullRequest
0 голосов
/ 27 августа 2018

У меня есть общая глобальная функция на PublishGitHub.groovy выглядит следующим образом:

#!/usr/bin/env groovy
def call(body)
{
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config

    echo "\u001B[32mINFO: Publishing...\u001B[m"
    body()
    echo "\u001B[32mINFO: End Publish...\u001B[m"      
}

И код на моем JenkinsFile:

environment {
    VERSION = "v1.3.${env.BUILD_NUMBER}"
}
stages {
    stage ('Publish WebAPI'){
        steps{
            echo "\u001B[32mINFO: Start Publish...\u001B[m"

            PublishGitHub{
                echo "This is a body with version: ${env.VERSION}"
            }               
        }
    }
}

И это мой вывод:

[Pipeline] echo
INFO: Start Publish...
[Pipeline] echo
INFO: Publishing...
[Pipeline] }

И следуйте следующей ошибке:

java.lang.NullPointerException: Невозможно получить свойство 'VERSION' в null объект

Потому что внутри тела у меня нет доступа к переменным окружения?

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Код вашей совместно используемой библиотеки выполняется вне контекста CPS рабочего процесса, поэтому закрытие, которое вы передаете сценарию vars, не распознает свойство env. Вы можете решить эту проблему, передав ссылку на сценарий рабочего процесса. Если вы называете свою функцию следующим образом

PublishGitHub(this) {
    echo "This is a body with version: ${env.VERSION}"
}

и вы применяете небольшую модификацию к сценарию vars/PublishGitHub.groovy, например:

#!/usr/bin/env groovy

def call(config, body) {
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config

    echo "\u001B[32mINFO: Publishing...\u001B[m"
    body()
    echo "\u001B[32mINFO: End Publish...\u001B[m"
}

тогда вы успешно запустите свой конвейер:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Publish WebAPI)
[Pipeline] echo
[32mINFO: Start Publish...[m
[Pipeline] echo
[32mINFO: Publishing...[m
[Pipeline] echo
This is a body with version: v1.3.537
[Pipeline] echo
[32mINFO: End Publish...[m
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Если вы хотите ограничить область действия совместно используемой библиотеки, вы всегда можете просто передать env вместо this и изменить vars/PublishGitHub.groovy на что-то вроде этого:

#!/usr/bin/env groovy

def call(env, body) {
    def config = [
            env: env
    ]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config

    echo "\u001B[32mINFO: Publishing...\u001B[m"
    body()
    echo "\u001B[32mINFO: End Publish...\u001B[m"
}

В этом сценарии вы предоставляете вашей общей библиотеке доступ только к переменным среды.

0 голосов
/ 03 января 2019

ответ Шимона работает. Я добавил "p.env = env"

def toParam(final Closure body) {
  final def p = [:]
  p.env = env
  body.resolveStrategy = Closure.DELEGATE_FIRST
  body.delegate = p
  body()
  return p
}
0 голосов
/ 28 августа 2018

Чтобы переменные среды, которые вы определили в своем Jenkinsfile, были доступны в коде вашей общей библиотеки, вы должны передать параметр this при вызове метода вашей общей библиотеки.

Например (ниже приведен частичный фрагмент только полного файла конвейера):

// JENKINS-42730
@Library('pipeline-shared-library')_
import org.blah.MySharedLibraryClass
// END JENKINS_42730

pipeline {
     agent { any }

     environment {
         FOO = (new MySharedLibraryClass(config, this)).myMethod("StringVar1", "StringVar2")

     }
}

Моя общая библиотека:

package org.blah

import groovy.text.SimpleTemplateEngine

public class MySharedLibraryClass implements Serializable {
    def engine = new SimpleTemplateEngine()
    def config
    def steps

    def ArtifactoryHelper(config, steps) {
        this.config = config
        this.steps = steps
    }

    def log(msg){
        //Allows me to print to Jenkins console
        steps.println(msg)
    }

    def myMethod(var1, var2) {
        ....
    }

Параметр this, о котором я говорил выше, соответствует шагам в коде общей библиотеки. После этого вы сможете разрешить "VERSION=${steps.env.VERSION}" в коде вашей общей библиотеки.

Также смотрите этот пост .

Примечания:

  1. pipeline-shared-library - это идентификатор, который я дал библиотеке в разделе «Управление Jenkins»> «Настроить систему» ​​
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...