Esecuzione condizionale delle pipeline in Azure DevOps

di Matteo Tumiati, in DevOps,

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi