Uno dei vantaggi che abbiamo nell'utilizzare le pipeline YAML è sicuramente rappresentato dalla possibilità di poter condividere e riutilizzare porzioni di codice (della pipeline stessa) tramite l'uso dei template. Questi template, infatti, non sono altro che un'estensione della pipeline che, al contrario della pipeline non possono essere invocati singolarmente e quindi devono essere richiamati da una pipeline definition ma, esattamente come una pipeline, accettano in ingresso una serie di parametri.
I template vengono richiamati dalla pipeline "principale" (o da altri template) esattamente come un task ma, a differenza di questi, non è possibile skippare l'esecuzione di tutto un template al verificarsi di una determinata condizione facendo l'uso di condition, come mostrato nell'esempio seguente:
- template: myTemplate.yml condition: succeeded()
Per ovviare a questo, quindi, possiamo aggiungere un parametro in input al file dei parametri:
steps: - powershell: Write-Host "##vso[task.setvariable variable=shouldExecute;isOutput=true]true" # oppure false, per verificare il comportamento opposto name: SetConditionalExecution - template: myTemplate.yml parameters: run_if: eq(variables['SetConditionalExecution.shouldExecute'], true))
Il valore che decide se il template verrà eseguito o no fa parte dei parametri di input al template stesso ed essendo generato a runtime tramite lo script di PowerShell, non possiamo andare ad utilizzare la sintassi statica ${{ if }} per capire se eseguire o no in blocco tutti i task contenuti nel template. Per ovviare al problema, di nuovo, facciamo un workaround includendo la condizione di esecuzione in ciascun task del template tramite l'uso di condition:
parameters: - name: run_if default: true steps: - task: PowerShell@2 condition: | and ( ${{ parameters.run_if }}, succeeded() ) inputs: targetType: 'inline' script: Write-Host "Sono in esecuzione"
Il controllo doppio su run_if e succeeded è necessario poichè mentre il primo controlla e stabilisce l'esecuzione condizionale, il secondo determina se il task deve essere eseguito o meno, in base all'output generato dai task precedenti. Di default, infatti, succeeded è applicato a tutti i task e quindi è implicito nella pipeline, ma poichè stiamo andando ad applicare una condizione custom e magari vogliamo mantenere il comportamento di default dove la pipeline si deve fermare e andare in errore quando un task ha fallito l'esecuzione, è bene applicare il controllo.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Combinare Container Queries e Media Queries
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Bloccare l'esecuzione di un pod in mancanza di un'artifact attestation di GitHub
Utilizzare QuickGrid di Blazor con Entity Framework
.NET Conference Italia 2024
Utilizzare la funzione EF.Parameter per forzare la parametrizzazione di una costante con Entity Framework
Rinnovare il token di una GitHub App durante l'esecuzione di un workflow
Referenziare un @layer più alto in CSS
Rendere le variabili read-only in una pipeline di Azure DevOps
Utilizzare gRPC su App Service di Azure
Generare la software bill of material (SBOM) in GitHub
Gestire la cancellazione di una richiesta in streaming da Blazor