Crea la tua prima pipeline dichiarativa Jenkins per CI/CD

Crea una prima pipeline dichiarativa Jenkins con stage, agent, checkout, test, gate di distribuzione, credenziali e azioni post.

Crea la tua prima pipeline dichiarativa Jenkins per CI/CD

La tua prima pipeline dichiarativa Jenkins dovrebbe rispondere a una domanda pratica: Jenkins può fare il checkout del tuo codice, compilarlo, testarlo ed eseguire i passaggi di distribuzione solo quando il branch corretto supera i test? Un Jenkinsfile ti fornisce questo flusso di lavoro come codice nello stesso repository della tua applicazione.

La sintassi dichiarativa è un buon punto di partenza perché fornisce una struttura prevedibile: pipeline, agent, stages, steps e post.

Comprendere la struttura della pipeline dichiarativa

La pipeline dichiarativa definisce l'intero flusso di lavoro in un file chiamato Jenkinsfile, che viene archiviato insieme al codice dell'applicazione nel tuo repository SCM (ad esempio Git). Questa pratica è nota come Pipeline as Code.

Elementi fondamentali di una pipeline dichiarativa

Una pipeline dichiarativa deve contenere i seguenti blocchi di primo livello:

  1. pipeline: Il blocco più esterno obbligatorio che definisce il contenuto della pipeline.
  2. agent: Specifica dove verrà eseguita la pipeline o uno stage specifico (ad esempio any, none o etichette specifiche).
  3. stages: Contiene uno o più blocchi stage sequenziali.
  4. stage: Definisce un blocco concettuale di lavoro (ad esempio Build, Test, Deploy).
  5. steps: Contiene uno o più comandi o funzioni eseguiti all'interno di uno stage.
pipeline {
    agent any 
    environment { // Opzionale: Definisce le variabili d'ambiente
        APP_VERSION = '1.0.0'
    }
    stages {
        stage('Build') {
            steps {
                // I comandi vanno qui
            }
        }
    }
    post { // Opzionale: Azioni eseguite dopo il completamento della pipeline
        always { 
            echo 'Pipeline terminata.' 
        }
    }
}

Passo 1: Configurare il job Jenkins

Per eseguire una pipeline dal codice, devi configurare un job Jenkins per leggere il Jenkinsfile dal tuo repository.

  1. Vai alla dashboard di Jenkins e seleziona Nuovo elemento.
  2. Inserisci un nome per la tua pipeline (ad esempio my-first-ci-pipeline).
  3. Seleziona il tipo di elemento Pipeline e clicca OK.
  4. Nella pagina di configurazione, scorri fino alla sezione Pipeline.
  5. Cambia la definizione da Pipeline script a Pipeline script da SCM.
  6. Seleziona il tuo SCM (ad esempio Git).
  7. Inserisci l'URL del repository e configura le credenziali se necessario.
  8. Assicurati che il Percorso dello script sia impostato su Jenkinsfile (il valore predefinito).

Passo 2: Definire il Jenkinsfile per CI/CD

Creeremo un Jenkinsfile completo che simula un semplice flusso di lavoro CI/CD, integrando stage standard per una distribuzione di successo.

Supponiamo di avere una struttura di repository contenente il codice sorgente dell'applicazione (ad esempio un semplice progetto Python o Java) e il Jenkinsfile nella radice.

Esempio completo di pipeline dichiarativa

Questa pipeline utilizza l'agente node (se configurato) e utilizza passaggi shell di base (sh) per simulare il lavoro reale. Lo stage di distribuzione è condizionale e viene eseguito solo al completamento con successo degli stage precedenti.

// Jenkinsfile
pipeline {
    // 1. Definizione dell'agente: Specifica dove viene eseguita l'intera pipeline
    agent { 
        label 'my-build-agent' // Usa un'etichetta specifica se disponibile, altrimenti 'any'
    }
    
    // 2. Variabili d'ambiente: Definisce le variabili utilizzabili in tutta la pipeline
    environment {
        CONTAINER_REGISTRY = 'registry.example.com'
        IMAGE_NAME = 'myapp'
    }
    
    stages {
        
        // Stage 1: Checkout (Gestione del codice sorgente)
        stage('Checkout Sorgente') {
            steps {
                // Il passaggio 'checkout scm' esegue automaticamente il checkout del codice
                // in base alla configurazione definita nelle impostazioni del job Jenkins.
                checkout scm
                sh 'echo "Codice sorgente estratto con successo."'
            }
        }
        
        // Stage 2: Compilazione degli artefatti
        stage('Compila Artefatto') {
            steps {
                sh 'echo "Avvio compilazione per $IMAGE_NAME:$BUILD_ID"'
                // Simulazione: Compila un'immagine Docker o un file jar/war
                sh "docker build --label build_id=${BUILD_ID} -t ${CONTAINER_REGISTRY}/${IMAGE_NAME}:${BUILD_ID} ."
            }
        }
        
        // Stage 3: Test e controlli di qualità
        stage('Esegui Test') {
            steps {
                sh './run_unit_tests.sh'
                sh 'echo "Esecuzione test di integrazione..."'
                // Esempio di raccolta dei risultati dei test (richiede plugin appropriati)
                // junit '**/target/surefire-reports/*.xml'
            }
        }
        
        // Stage 4: Distribuzione (Condizionale)
        stage('Distribuisci in Staging') {
            // La direttiva 'when' garantisce che lo stage venga eseguito solo in condizioni specifiche
            when {
                branch 'main'
            }
            steps {
                sh "docker push ${CONTAINER_REGISTRY}/${IMAGE_NAME}:${BUILD_ID}"
                sh 'kubectl apply -f k8s/deployment-staging.yaml'
                script {
                    // I blocchi script consentono logica Groovy tradizionale all'interno dei passaggi dichiarativi
                    echo "Distribuzione riuscita nell'ambiente di Staging."
                }
            }
        }
    }
    
    // 3. Azioni post: Definisce le azioni in base allo stato finale della pipeline
    post {
        success {
            echo 'Pipeline completata con successo. Notifica al team tramite Slack...'
            // slackSend channel: '#devops-alerts', message: 'CI/CD Success!'
        }
        failure {
            echo 'Pipeline fallita. Controlla i log per gli errori.'
        }
        cleanup {
            sh 'docker image prune -f --filter "label=build_id=$BUILD_ID"'
        }
    }
}

Passo 3: Eseguire e monitorare la pipeline

Una volta che il Jenkinsfile è stato committato e inviato al branch configurato nel tuo job Jenkins:

  1. Nella pagina del job Jenkins, clicca Build Now (o attendi il polling SCM/trigger webhook).
  2. Monitora la build nel pannello Cronologia build.
  3. Clicca sul numero della build in esecuzione e seleziona Output console per visualizzare i dettagli dell'esecuzione passo dopo passo.
  4. Puoi anche utilizzare la visualizzazione Stage View (se il plugin è installato) per vedere graficamente l'avanzamento degli stage Checkout, Build, Test e Deploy.

Best practice e funzionalità avanzate

Utilizzo di librerie e codice condiviso

Per passaggi complessi o altamente ripetitivi, evita di scrivere Groovy dettagliato direttamente nel Jenkinsfile. Utilizza invece Librerie condivise. Queste librerie esterne ti consentono di definire funzioni comuni (come routine di distribuzione standard o funzioni di notifica) che possono essere chiamate da più pipeline, rendendo il tuo Jenkinsfile più pulito.

// Chiamata a un passaggio di libreria condivisa
stage('Configurazione Personalizzata') {
    steps {
        customLibrary.initializeEnvironment(env: 'prod')
    }
}

Lavorare con le credenziali

Non codificare mai informazioni sensibili (password, token, chiavi API) direttamente nel Jenkinsfile. Utilizza il sistema integrato di Gestione delle credenziali di Jenkins.

Il passaggio withCredentials ti consente di accedere in modo sicuro ai segreti archiviati:

stage('Autentica Registro') {
    steps {
        withCredentials([usernamePassword(credentialsId: 'docker-registry-creds', 
                                          passwordVariable: 'PASS', 
                                          usernameVariable: 'USER')]) {
            sh '''
                printf '%s' "$PASS" | docker login \
                  --username "$USER" \
                  --password-stdin "$CONTAINER_REGISTRY"
            '''
        }
    }
}

Selezione dell'agente

Suggerimento: Definisci sempre il tuo agent in modo specifico utilizzando un'label piuttosto che agent any. Usare agent any significa che la pipeline potrebbe essere eseguita sul nodo controller di Jenkins, il che rappresenta un rischio per la sicurezza e può influire sulle prestazioni del controller. Assicurati di aver configurato correttamente gli agenti Jenkins (nodi) con gli strumenti necessari (Docker, Maven, Node.js) installati.

Conclusione

Mantieni la prima pipeline semplice e affidabile: scegli un'etichetta agente reale, fai il checkout del codice, compila, testa, controlla la distribuzione per branch e mantieni i segreti nelle credenziali Jenkins. Una volta che funziona, aggiungi la pubblicazione degli artefatti, la scansione della sicurezza e la promozione dell'ambiente un passo alla volta.