Condividi tramite


Eseguire la migrazione da Jenkins ad Azure Pipelines

Servizi di Azure DevOps

Jenkins, un server di automazione open source, viene tradizionalmente installato dalle aziende nei propri data center e gestiti in locale. Molti provider offrono anche l'hosting gestito di Jenkins.

In alternativa, Azure Pipelines è una pipeline di integrazione continua nativa del cloud. Fornisce la gestione delle pipeline a più fasi e delle macchine virtuali di Azure, che sono ospitate nel cloud come agenti di compilazione.

Azure Pipelines offre anche un'opzione completamente locale con Azure DevOps Server, per i clienti che hanno problemi di conformità o sicurezza che richiedono di mantenere il codice e gestire le build all'interno del data center aziendale.

Azure Pipelines supporta anche modelli cloud ibridi e locali. Azure Pipelines può gestire l'orchestrazione di compilazione e rilascio e abilitare gli agenti di compilazione, sia nel cloud che installati in locale.

Questo articolo fornisce una guida per tradurre una configurazione di pipeline Jenkins in Azure Pipelines. Include informazioni sullo spostamento di compilazioni basate su contenitori e sulla selezione degli agenti di compilazione, sul mapping delle variabili di ambiente e su come gestire l'esito positivo e negativo della pipeline di compilazione.

Configurazione

Si noterà una transizione familiare da una pipeline dichiarativa Jenkins a una configurazione YAML di Azure Pipelines. I due sono concettualmente simili, supportando la "configurazione come codice" e consentendo di controllare la configurazione nel sistema di controllo della versione. A differenza di Jenkins, tuttavia, Azure Pipelines usa yaML standard del settore per configurare la pipeline di compilazione.

I concetti tra Jenkins e Azure Pipelines e il modo in cui sono configurati sono simili. Un jenkinsfile elenca una o più fasi del processo di compilazione, ognuna delle quali contiene uno o più passaggi eseguiti in ordine. Ad esempio, una fase di "compilazione" può eseguire un'attività per installare le dipendenze in fase di compilazione, quindi eseguire un passaggio di compilazione. Mentre una fase di "test" può richiamare il framework di test sui file binari prodotti nella fase di compilazione.

Per esempio:

Jenkinsfile

pipeline {
    agent none
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
                sh 'npm run build'
            }
        }
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }
}

Il jenkinsfile si traduce facilmente in una configurazione YAML di Azure Pipelines, con un processo corrispondente a ogni fase e i passaggi da eseguire in ogni processo:

azure-pipelines.yml

jobs:
- job: Build
  steps:
  - script: npm install
  - script: npm run build
- job: Test
  steps:
  - script: npm test

Compilazioni basate su contenitori

L'uso di contenitori nella pipeline di compilazione consente di compilare e testare all'interno di un'immagine Docker con le dipendenze esatte richieste dalla pipeline, già configurate. Consente di evitare di dover includere un passaggio di compilazione che installa più software o configura l'ambiente. Sia Jenkins che Azure Pipelines supportano compilazioni basate su contenitori.

Inoltre, sia Jenkins che Azure Pipelines consentono di condividere la directory di build nell'agente host al volume del contenitore usando il flag -v per docker. In questo modo è possibile concatenare più processi di compilazione che possono usare le stesse origini e scrivere nella stessa directory di output. Ciò è particolarmente utile quando si usano molte tecnologie diverse nello stack; è possibile creare il back-end usando un contenitore .NET Core e il front-end con un contenitore TypeScript.

Ad esempio, per eseguire una compilazione in un contenitore Ubuntu 22.04 ("Jammy"), eseguire i test in un contenitore Ubuntu 24.04 ("Noble"):

Jenkinsfile

pipeline {
    agent none
    stages {
        stage('Build') {
            agent {
                docker {
                    image 'ubuntu:jammy'
                    args '-v $HOME:/build -w /build'
                }
            }
            steps {
                sh 'make'
            }
        }
        stage('Test') {
            agent {
                docker {
                    image 'ubuntu:noble'
                    args '-v $HOME:/build -w /build'
                }
            }
            steps {
                sh 'make test'
            }
        }
    }
}

Azure Pipelines offre processi di contenitore che consentono di eseguire la compilazione all'interno di un contenitore:

azure-pipelines.yml

resources:
  containers:
  - container: jammy
    image: ubuntu:jammy
  - container: noble
    image: ubuntu:noble

jobs:
- job: build
  container: jammy
  steps:
  - script: make
- job: test
  dependsOn: build
  container: noble
  steps:
  - script: make test

Azure Pipelines offre inoltre un'attività Docker che consente di eseguire, compilare o eseguire il push di un'immagine.

Selezione agente

Jenkins offre la selezione dell'agente di compilazione usando l'opzione agent per assicurarsi che la pipeline di compilazione, o una fase specifica della pipeline, venga eseguita in un determinato computer dell'agente di compilazione. Analogamente, Azure Pipelines offre molte opzioni per configurare la posizione in cui viene eseguito l'ambiente di compilazione.

Selezione dell'agente ospitato

Azure Pipelines offre agenti di compilazione ospitati nel cloud per build Linux, Windows e macOS. Per selezionare l'ambiente di compilazione, è possibile usare vmimage parola chiave. Ad esempio, per selezionare una build macOS:

pool:
  vmimage: macOS-latest

Inoltre, è possibile specificare un container e un'immagine Docker per un controllo più dettagliato su come viene eseguita la compilazione.

Selezione dell'agente locale

Se si ospitano gli agenti di compilazione in locale, è possibile definire l'agente di compilazione "funzionalità" in base all'architettura del computer o al software installato. Ad esempio, se è stato configurato un agente di compilazione locale con le java funzionalità , è possibile assicurarsi che il processo venga eseguito usando la demands parola chiave :

pool:
  demands: java

Variabili di ambiente

In Jenkins si definiscono in genere le variabili di ambiente per l'intera pipeline. Ad esempio, per impostare due variabili di ambiente, CONFIGURATION=debug e PLATFORM=x86:

Jenkinsfile

pipeline {
    agent any
    environment {
        CONFIGURATION = 'debug'
        PLATFORM      = 'x64'
    }
    stages {
        stage('Build') {
            steps {
                sh 'echo $CONFIGURATION $PLATFORM'
            }
        }
    }
}

Analogamente, in Azure Pipelines è possibile configurare variabili usate sia all'interno della configurazione YAML che come variabili di ambiente durante l'esecuzione del processo:

azure-pipelines.yml

variables:
  configuration: debug
  platform: x64

Inoltre, in Azure Pipelines è possibile definire variabili impostate solo durante un determinato processo:

azure-pipelines.yml

jobs:
- job: debug build
  variables:
    configuration: debug
  steps:
  - script: ./build.sh $(configuration)
- job: release build
  variables:
    configuration: release
  steps:
  - script: ./build.sh $(configuration)

Variabili predefinite

Sia Jenkins che Azure Pipelines impostano una serie di variabili di ambiente che consentono di esaminare e interagire con l'ambiente di esecuzione del sistema di integrazione continua.

Description Jenkins Azure Pipelines
Identificatore numerico univoco per la chiamata di compilazione corrente. BUILD_NUMBER BUILD_BUILDNUMBER
Identificatore univoco (non necessariamente numerico) per la chiamata di compilazione corrente. BUILD_ID BUILD_BUILDID
URL che visualizza i log di compilazione. BUILD_URL Questo valore non è impostato come variabile di ambiente in Azure Pipelines, ma è possibile derivarlo da altre variabili. 1
Nome del computer su cui viene eseguita la compilazione corrente. NODE_NAME AGENT_NAME
Nome del progetto o della definizione di compilazione. JOB_NAME RELEASE_DEFINITIONNAME
Stringa per l'identificazione del build; il numero del build è un buon identificatore univoco. BUILD_TAG BUILD_BUILDNUMBER
URL per l'host che esegue la compilazione. JENKINS_URL SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
Identificatore univoco per l'executor di compilazione o l'agente di compilazione attualmente in esecuzione. EXECUTOR_NUMBER AGENT_NAME
Posizione delle sorgenti estratte. WORKSPACE BUILD_SOURCESDIRECTORY
ID commit Git corrispondente alla versione del software in fase di compilazione. GIT_COMMIT BUILD_SOURCEVERSION
Percorso del repository Git su GitHub, Azure Repos o un altro provider di repository. GIT_URL BUILD_REPOSITORY_URI
Ramo Git in fase di compilazione. GIT_BRANCH BUILD_SOURCEBRANCH

1 Per derivare l'URL che visualizza i log di compilazione in Azure Pipelines, combinare le variabili di ambiente seguenti in questo formato:

${SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}/${SYSTEM_TEAMPROJECT}/_build/results?buildId=${BUILD_BUILDID}

Gestione del successo e del fallimento

Jenkins consente di eseguire comandi al termine della compilazione, usando la post sezione della pipeline. È possibile specificare i comandi eseguiti quando la compilazione ha esito positivo (usando la success sezione), quando la compilazione ha esito negativo (usando la failure sezione) o sempre (usando la always sezione). Per esempio:

Jenkinsfile

post {
    always {
        echo "The build has finished"
    }
    success {
        echo "The build succeeded"
    }
    failure {
        echo "The build failed"
    }
}

Analogamente, Azure Pipelines ha un framework di esecuzione condizionale avanzato che consente di eseguire un processo o di passaggi di un processo, in base a molte condizioni, tra cui esito positivo o negativo della pipeline.

Per emulare le condizioni di build di Jenkins post, è possibile definire lavori eseguiti in base alle condizioni always(), succeeded() o failed().

azure-pipelines.yml

jobs:
- job: always
  steps:
  - script: echo "The build has finished"
    condition: always()

- job: success
  steps:
  - script: echo "The build succeeded"
    condition: succeeded()

- job: failed
  steps:
  - script: echo "The build failed"
    condition: failed()

Annotazioni

Jenkins supporta condizioni aggiuntive post oltre always, success e failure:

  • changed: viene eseguito solo se l'esecuzione della pipeline corrente ha uno stato di completamento diverso rispetto all'esecuzione precedente.
  • fixed: viene eseguito solo se l'esecuzione corrente ha esito positivo e l'esecuzione precedente non è riuscita o è instabile.
  • unstable: viene eseguito solo se l'esecuzione della pipeline corrente ha uno stato "instabile" (in genere causato da errori di test).
  • cleanup: viene eseguito dopo che tutte le altre condizioni post sono state valutate, indipendentemente dallo stato della pipeline.

In Azure Pipelines è possibile ottenere funzionalità simili usando condizioni con espressioni come eq(variables['Agent.JobStatus'], 'SucceededWithIssues') per le compilazioni instabili.

È anche possibile combinare altre condizioni, ad esempio la possibilità di eseguire un'attività in base all'esito positivo o negativo di una singola attività, delle variabili di ambiente o dell'ambiente di esecuzione, per creare una pipeline di esecuzione avanzata.

Gestione delle credenziali

Jenkins fornisce un credentials() helper all'interno della environment direttiva per inserire in modo sicuro le credenziali nella pipeline. Jenkins supporta diversi tipi di credenziali, tra cui testo segreto, coppie nome utente/password e file segreti.

Jenkinsfile

pipeline {
    agent any
    environment {
        AWS_ACCESS_KEY_ID     = credentials('aws-access-key-id')
        AWS_SECRET_ACCESS_KEY = credentials('aws-secret-access-key')
    }
    stages {
        stage('Deploy') {
            steps {
                sh 'aws s3 ls'
            }
        }
    }
}

In Azure Pipelines è possibile gestire i segreti usando gruppi di variabili, integrazione di Azure Key Vault o definendo le variabili segrete direttamente nella pipeline:

azure-pipelines.yml

variables:
- group: my-aws-credentials  # Variable group linked to Azure Key Vault or containing secrets

jobs:
- job: Deploy
  steps:
  - script: aws s3 ls
    env:
      AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID)
      AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)

È anche possibile fare riferimento ai segreti direttamente da Azure Key Vault usando l'attività AzureKeyVault@2:

steps:
- task: AzureKeyVault@2
  inputs:
    azureSubscription: 'my-azure-subscription'
    KeyVaultName: 'my-key-vault'
    SecretsFilter: 'AWS-ACCESS-KEY-ID,AWS-SECRET-ACCESS-KEY'
- script: aws s3 ls
  env:
    AWS_ACCESS_KEY_ID: $(AWS-ACCESS-KEY-ID)
    AWS_SECRET_ACCESS_KEY: $(AWS-SECRET-ACCESS-KEY)