Jenkins e Groovy: Automação de Builds com Scripting

1 - Introdução ao Groovy

Groovy é uma linguagem de script dinâmica e tipagem leve, orientada a objetos e baseada na JVM. A sua sintaxe é bastante semelhante à do Java, mas com características dinâmicas mais flexíveis, suporte a closures e funções de ordem supreior. Groovy suporta inferência de tipo automática, eliminando a necessidade de especificar tipos de variáveis. É amplamente utilizado em ferramentas DSL, como Gradle, em programação mista com Java e, particularmente, no Jenkins para a criação de arquivos de configuração e implementação de automação em builds, testes e implantações.

Tutorial

2 - Configurando o ambiente Groovy no Windows 10

2.1 Instalação do JDK

Faça o download do pacote zip do OpenJDK e extraia para um diretório específico

Crie uma variável de ambiente JAVA_HOME com o valor do caminho onde o zip foi extraído JDK8: Adicione %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin à variável de ambiente PATH JDK17: Adicione %JAVA_HOME%\bin à variável de ambiente PATH Execute java -version e javac -version no prompt de comando. Se a versão for exibida sem mensagens de erro, a configuração está correta.

2.2 Instalação do Groovy SDK

Faça o download do pacote zip do Groovy SDK e extraia para um diretório específico

Configure a variável de ambiente GROOVY_HOME com o valor do caminho onde o zip foi extraído Adicione %GROOVY_HOME%\bin à variável de ambiente PATH Execute groovy -version no prompt de comando. Se a versão for exibida sem mensagens de erro, a instalação está correta.

2.3 Editor integrado do Groovy

Execute o comando groovyconsole no prompt de comando para iniciar o editor embutido, ideal para aprendizado e cenários simples

2.4 VS Code com Groovy

Primeiro, instale o plugin code-groovy: Melhor suporte para Groovy no VSCode

Depois, instale o plugin Code Runner: Executar trechos de código ou arquivos para múltiplas linguagens e comandos personalizados

Outros plugins

  • Jenkins Pipeline Linter Connector --- valida arquivos Jenkinsfile enviando-os ao Pipeline Linter de um servidor Jenkins
  • JenkinsFile Support --- Esta extensão adiciona suporte para realce de sintaxe de Jenkinsfiles
  • Groovy Lint, Format and Fix --- Análise de código, formatação e correção automática para código Groovy e Jenkinsfile
  • Jenkins Doc --- Fornece documentação do Jenkins e autocompletar para Jenkinsfile e arquivos Groovy

2.5 Desenvolvimento com Groovy usando IntelliJ IDEA

https://www.jetbrains.com/help/idea/groovy.htmlPor exemplo,

  1. Crie um novo Project, selecione Groovy, especifique o Project SDK e a Groovy library
  2. Especifique o nome do projeto, selecione o diretório src, clique com o botão direito e crie um novo arquivo Groovy, selecione Groovy Script e especifique o nome do arquivo
  3. No arquivo Groovy Script, digite println "Olá Groovy", pressione CTRL + SHIFT + F10 para executar.

3 - Escrita e Validação

3.1 Pipeline Web do Jenkins

Um arquivo Jenkinsfile simples pode ser escrito na página de Pipeline Web do Jenkins (com verificação de sintaxe embutida)

3.2 pipeline-syntax

Snippet Generator: https://<url do servidor jenkins>/pipeline-syntax/

3.3 Validação local de Jenkinsfile

Para evitar erros de sintaxe durante o desenvolvimento de pipelines Jenkins, pode-se usar plugins do VS Code para verificação. Valide seu Jenkinsfile dentro do VS Code: https://jenkins.io/blog/2018/11/07/Validate-Jenkinsfile/Pode-se usar o Visual Studio Code com o plugin Jenkins Pipeline Linter Connector para formatação e validação local de Jenkinsfile.

É necessário especificar os parâmetros do plugin nas configurações

- jenkins.pipeline.linter.connector.url 
- jenkins.pipeline.linter.connector.user
- jenkins.pipeline.linter.connector.pass 
- jenkins.pipeline.linter.connector.crumbUrl 


Nota:

  • Certifique-se de que o Jenkins tem "CSRF Protection" ativado (Manage Jenkins -> Manage Configure Global Security)
  • Na verdade, utiliza a API Jenkins para validação de sintaxe, não garantindo que o conteúdo do pipeline esteja completamente funcional

Exemplo: https://jenkins.ap.manulife.com/blueocean/

Execução do plugin: Botão direito -> Command Palette -> Validate Jenkinsfile ou usar o atalho Shift + Alt + V

4 - Exemplos de Sintaxe

Mais conteúdo sobre Groovy: http://www.groovy-lang.org/documentation.html


projeto = 'Automacao'  //variável definida fora do pipeline
ferramentas = ['Jenkins', 'GitLab', 'Maven', 'Sonar']
dados_usuario = ['codigo':200, 'login':'automa', 'nivel':'Admin']
grupos_usuarios = [
['codigo':201, 'login':'dev', 'nivel':'desenvolvedor'],
['codigo':202, 'login':'qa', 'nivel':'tester']
]

pipeline {
    agent {
        label 'master'
    }
    stages {
        stage('Tipos de Dados Comuns') {
            steps {
                script {
                    println('Tipo String: texto entre aspas simples ou duplas')
                    println('Tipo Booleano: true, false')
                    println('Tipos de Coleção: List, Map, Set')
                }
            }
        }
        stage('Manipulação de Strings') {
            steps {
                script {
                    println("Nome do Projeto: ${projeto}")  //imprime variável
                    nome_tarefa = 'app_automacao_CD'  //variável definida neste estágio
                    parte_nome = nome_tarefa.split('_')[0]  //divide string por delimitador
                    println(parte_nome)
                    println(nome_tarefa.contains('CD'))  //verifica se contém caractere específico
                    println("Tamanho: ${nome_tamanho.size()}")  //calcula tamanho da string
                    println("Comprimento: ${nome_tarefa.length()}")  //calcula comprimento da string
                    println("termina com 'CD': ${nome_tarefa.endsWith('CD')}")  //verifica fim da string
                }
            }
        }
        stage('Manipulação de Listas') {
            steps {
                script {
                    println("Lista: ${ferramentas}")
                    println(ferramentas + 'K8s')  //adiciona elemento à Lista
                    ferramentas.add('Docker')  //adiciona com método add()
                    println(ferramentas - 'Sonar')//remove elemento da Lista
                    println("Lista Atualizada: ${ferramentas}")
                    println(ferramentas.contains('Jenkins'))  //verifica existência de elemento
                    println("${ferramentas[0]},${ferramentas[-1]}")  //acessa primeiro e último elemento por índice
                }
            }
        }
        stage('Manipulação de Maps') {
            steps {
                script {
                    println("Mapa: ${dados_usuario}")
                    println(dados_usuario['codigo'])  //acessa valor por chave
                    println(dados_usuario['login'])
                    println(dados_usuario.containsKey('login'))  //verifica existência de chave
                    println(dados_usuario.containsValue(200))  //verifica existência de valor
                    println(dados_usuario.keySet())  //exibe chaves do mapa
                    dados_usuario['login'] = 'JenkinsX'  //reatribui valor
                    println(dados_usuario)
                    dados_usuario.remove('nivel')  //remove chave específica
                    println(dados_usuario)
                }
            }
        }
        stage('Estruturas de Controle') {
            steps {
                script {
                    if (projeto == 'Automacao') {
                        println('projeto é Automacao')
                    } else if (projeto == 'Integracao') {
                        println('projeto é Integracao')
                    } else {
                        println('erro...')
                    }
                }
                script {
                    switch(projeto) {
                        case 'Integracao': println('projeto é Integracao')
                        break
                        case 'Automacao': println('projeto é Automacao')
                        break
                        default: println('erro...')
                        break
                    }
                }
                script {
                    for (item in ferramentas) {
                        println(item)
                    }
                }              
            }
        }
        stage('Funções') {
            steps {
                script {
                    nome_usuario = ObterNomePorCodigo(201)
                    println(nome_usuario)
                }
            }
        }
    }
}

def ObterNomePorCodigo(int codigo) {
    for (usuario in grupos_usuarios) {
        if (usuario['codigo'] == codigo) {
            return usuario['login']
        }
    }
}



5 - Referências

6 - Dicas

1 - Formatação de código Groovy

  • VScode: Associe tipo de arquivo, reconhecendo arquivos com extensão .groovy como .js, depois use "Formatar Documento" para indentação
  • IntelliJ IDEA: Suporta autocompletar, realce de sintaxe e erros, formatação e verificação de código, refatoração e depuração para Groovy

Associação de tipo de arquivo https://code.visualstudio.com/docs/languages/overview#_adding-a-file-extension-to-a-language

Tags: Jenkins Groovy Automação CI/CD Pipeline

Publicado em 6-11 06:07 por Thomas