Jenkins: não é possível definir a variável no estágio do pipeline

106

Estou tentando criar um script de pipeline declarativo do Jenkins, mas estou tendo problemas com a declaração de variável simples.

Aqui está o meu script:

pipeline {
   agent none
   stages {
       stage("first") {
           def foo = "foo" // fails with "WorkflowScript: 5: Expected a step @ line 5, column 13."
           sh "echo ${foo}"
       }
   }
}

No entanto, recebo este erro:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 5: Expected a step @ line 5, column 13.
           def foo = "foo"
           ^

Estou no Jenkins 2.7.4 e no Pipeline 2.4.

Malcolm Crum
fonte

Respostas:

101

O modelo declarativo para Jenkins Pipelines tem um subconjunto restrito de sintaxe que permite nos stageblocos - consulte o guia de sintaxe para obter mais informações . Você pode contornar essa restrição envolvendo suas etapas em um script { ... }bloco, mas, como resultado, você perderá a validação da sintaxe, dos parâmetros, etc. dentro do scriptbloco.

abayer
fonte
5
E se eu quiser usar essa variável fora do bloco de script?
Jan Steinke,
3
para usar a variável fora do bloco de script, verifique este stackoverflow.com/questions/43879733/…
Senthil A Kumar
56

Acho que o erro não está vindo da linha especificada, mas das primeiras 3 linhas. Em vez disso, tente isto:

node {
   stage("first") {
     def foo = "foo"
     sh "echo ${foo}"
   }
}

Acho que você teve algumas linhas extras que não são válidas ...

EDITAR

Pela documentação do modelo de pipelineenvironment declarativo , parece que você precisa usar um bloco de declaração para declarar suas variáveis, por exemplo:

pipeline {
   environment {
     FOO = "foo"
   }

   agent none
   stages {
       stage("first") {
           sh "echo ${FOO}"
       }
   }
}
Pom12
fonte
1
Você também pode adicionar um bloco de ambiente em um estágio (por exemplo, se sua variável depende de algo feito em uma etapa anterior).
Tereza Tomcova
34

Concordo com @ Pom12, @abayer. Para completar a resposta, você precisa adicionar um bloco de script

Experimente algo assim:

pipeline {
    agent any
    environment {
        ENV_NAME = "${env.BRANCH_NAME}"
    }

    // ----------------

    stages {
        stage('Build Container') {
            steps {
                echo 'Building Container..'

                script {
                    if (ENVIRONMENT_NAME == 'development') {
                        ENV_NAME = 'Development'
                    } else if (ENVIRONMENT_NAME == 'release') {
                        ENV_NAME = 'Production'
                    }
                }
                echo 'Building Branch: ' + env.BRANCH_NAME
                echo 'Build Number: ' + env.BUILD_NUMBER
                echo 'Building Environment: ' + ENV_NAME

                echo "Running your service with environemnt ${ENV_NAME} now"
            }
        }
    }
}
Si Zi
fonte
4
Observe que este exemplo assume que já existe uma variável de ambiente definida "ENVIRONMENT_NAME" acessível a jenkins.
Alberto
1
O bloco de script pode alterar os valores do ambiente?
pitchblack408
Sim, você pode alterar o valor do ambiente dentro do bloco de script.
NicoPaez
8

No Jenkins 2.138.3, existem dois tipos diferentes de pipelines.

Pipelines declarativos e com script.

"Pipelines declarativos são uma nova extensão do DSL de pipeline (é basicamente um script de pipeline com apenas uma etapa, uma etapa de pipeline com argumentos (chamados de diretivas), essas diretivas devem seguir uma sintaxe específica. O objetivo desse novo formato é que é mais estrito e, portanto, deve ser mais fácil para os iniciantes em pipelines, permite a edição gráfica e muito mais. pipelines com script são a alternativa para requisitos avançados. "

pipeline de Jenkins: agente vs nó?

Aqui está um exemplo de uso de variáveis ​​de ambiente e globais em um pipeline declarativo. Pelo que posso dizer, os ambientes ficam estáticos depois de configurados.

def  browser = 'Unknown'

pipeline {
    agent any
    environment {
    //Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
    IMAGE = readMavenPom().getArtifactId()
    VERSION = readMavenPom().getVersion()


    }
    stages {
        stage('Example') {
            steps {
                script {
                    browser = sh(returnStdout: true, script: 'echo Chrome')
                }
            }
        }
        stage('SNAPSHOT') {
                when {
                    expression { 
                        return !env.JOB_NAME.equals("PROD") && !env.VERSION.contains("RELEASE")
                    }
                }
                steps {
                    echo "SNAPSHOT"
                    echo "${browser}"
                }
            }
            stage('RELEASE') {
                when {
                    expression { 
                        return !env.JOB_NAME.equals("TEST") && !env.VERSION.contains("RELEASE")
                    }
                }
                steps {
                    echo "RELEASE"
                    echo "${browser}"
                }
            }
    }//end of stages 
}//end of pipeline
pitchblack408
fonte
Recebo o seguinte erro no código acima: [Pipeline] Início do pipeline [Pipeline] readMavenPom [Pipeline] Fim do pipeline org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Classe de contexto necessária hudson.FilePath ausente Talvez você tenha esquecido de cercar o código com uma etapa que fornece isso, como: node
mancocapac
Não, funcionou como está. É um pipeline declarativo. Agente qualquer significa que pode funcionar em qualquer nó
pitchblack408
@ pitchblack408, você está correto, eu tinha [nenhum agente] no topo do meu pipeline. Não tem certeza do que você quer dizer com: o ambiente fica estático depois de definido? Eles podem ser alterados em um script, por exemplo, script {IMAGE = "newVal}
mancocapac
Exemplo, olhe para IMAGEM. Não é uma variável que pode ou deve ser alterada pelos pipelines. É meu entendimento que deve ser tratado como um valor estático após a definição como parte do ambiente.
pitchblack408
0

Você está usando um Pipeline Declarativo que requer uma etapa de script para executar o código Groovy. Essa é uma grande diferença em comparação com o Pipeline com script, onde isso não é necessário.

A documentação oficial diz o seguinte:

A etapa de script pega um bloco de pipeline com script e o executa no pipeline declarativo.

pipeline {
   agent none
   stages {
       stage("first") {
           script {
               def foo = "foo" 
               sh "echo ${foo}"
           }
       }
   }
}
Michael Kemmerzell
fonte