Le pipeline che costruiamo sono un insieme di step che vengono eseguiti in sequenza per raggiungere un determinato scopo. Tuttavia, molte volte, ci troviamo davanti una strada non proprio lineare e, magari, quello che vogliamo fare è eseguire percorsi diversi basandoci su determinate condizioni. Un esempio, può essere quello di eseguire i test di integrazione solo nel momento in cui eseguiamo la build di CI e non durante le pull request, piuttosto che caricare i log risultato di un'operazione indipendentemente dal fatto che l'operazione sia andata a buon fine oppure no.
In Azure DevOps esistono due tipologie di condizioni che possono essere applicate: espressioni condizionali e veri e propri statement condizionali. La differenza tra i due è abbastanza semplice e tutto sommato può essere riassunta dicendo che le espressioni vengono valutate a runtime, durante l'esecuzione della pipeline stessa, mentre gli statement vengono calcolati al tempo di costruzione della pipeline (che possiamo chiamare impropriamente a design-time). Tutto questo, sebbene può sembrare poco significativo, introduce delle differenze sostanziali nelle pipeline: nel caso delle expression, infatti, la pipeline viene eseguita per intero e, solo quando lo step (vale anche per job e stage) sta per essere invocato, viene valutata l'espressione di ingresso e quindi il task viene eseguito oppure skippato, mentre nel caso degli statement condizionali, l'espressione viene valutata prima di avviare l'esecuzione della pipeline stessa, pertanto step, job o stage interi possono letteralmente scomparire dalla pipeline, con consequenze anche pericolose sui task successivi (in quanto possono esserci condizioni dipendenti dagli step precedenti).
Valutiamo un caso di expression:
jobs: - job: A displayName: Job A continueOnError: true steps: - script: echo Job A ran - script: exit 1 - job: B dependsOn: A condition: eq(dependencies.A.result,'SucceededWithIssues') displayName: Job B steps: - script: echo Job B ran
Se guardiamo la pipeline, noteremo come il job "A" venga eseguito lanciando in sequenza i due script che generano un errore. Nel job "B", invece, è stata applicata una condizione che ne permette l'esecuzione solamente se il job "A" ha terminato con un risultato di tipo "SucceededWithIssues", ovvero completato con alcuni warning. Nel caso in cui la condition fosse "Succeeded", invece, il job "B" non verrebbe mai eseguito perché, chiaramente, il job "A" continuerà a generare l'exit code che indica un insuccesso nell'operazione. E' abbastanza evidente che, in questo caso, la condizione può essere calcolata solamente al momento, quindi mentre la pipeline si sta eseguendo (anche se la casistica è un po' ambigua perché il task produce sempre un errore, ma rappresenta un caso limite e di esempio).
Gli statement condizionali, invece, ci consentono di mettere dei veri e propri "if" all'interno della pipeline:
parameters: - name: executeScript type: boolean steps: - ${{ if eq(parameters.executeScript, true) }}: - script: echo 'Running'
Lo script rappresenta non una intera pipeline, ma solamente un template, in questo caso, quindi il parametro "executeScript" viene valutato al momento della costruzione della pipeline perché è la pipeline stessa che lo deve produrre prima di essere eseguita. La condizione viene quindi valutata prima della partenza della pipeline ed il task che stampa la stringa "Running" esisterà o no a seconda del valore passato dal parametro.
Questa condizione ci consente di includere anche step, job, interi stage o addirittura variabili custom a seconda di condizioni iniziali.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Ottimizzazione dei block template in Angular 17
Eseguire le GitHub Actions offline
Creare un webhook in Azure DevOps
Migliorare l'organizzazione delle risorse con Azure Policy
Utilizzare un service principal per accedere a Azure Container Registry
Assegnare un valore di default a un parametro di una lambda in C#
Ottenere un token di accesso per una GitHub App
Sostituire la GitHub Action di login su private registry
Creare una custom property in GitHub
Generare velocemente pagine CRUD in Blazor con QuickGrid
Migrare una service connection a workload identity federation in Azure DevOps
I più letti di oggi
- Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
- Creare una libreria CSS universale: Cards
- Eseguire script pre e post esecuzione di un workflow di GitHub