Al contrario di quanto avviene in Azure DevOps, con i workflow di GitHub non è propriamente possibile poter ri-eseguire un singolo (o una serie di) step, se questi fanno parte di un ciclo. In Azure DevOps, infatti, è possibile eseguire un loop di operazioni semplicemente marcando il codice con lo statement eachname:
steps: - ${{ each value in parameters.myArray }}: - script: echo ${{ value }}
Questo è particolarmente utile quando abbiamo più input che devono essere valutati allo stesso modo, oppure che sono necessari a produrre dell'output che verrà poi valutato in uno step successivo. In GitHub non esiste, al momento, un concetto simile. Usando però le matrici e l'output generato da un job precedente, possiamo realizzare un comportamento simile.
Parlando concenttualmente, l'obiettivo è quello di sfruttare un job primario per generare un array di elementi che poi verranno sfruttati dal secondo job che, di fatto, viene utilizzato come rimpiazzo per effettuare i cicli. Infatti, il job successivo non viene mai renderizzato a "template time" quando la pipeline è avviata, ma viene valutato come è disponibile il risultato degli step precedenti. Vediamo il codice per realizzarlo.
name: Repeatable steps on: workflow_dispatch: jobs: setup: runs-on: ubuntu-latest outputs: matrix: ${{ steps.matrix.outputs.value }} steps: - id: matrix run: | echo '::set-output name=value::[ "loop1", "loop2", "loop3" ]' build: needs: [ setup ] runs-on: ubuntu-latest strategy: matrix: value: ${{ fromJson(needs.setup.outputs.matrix) }} steps: - run: | echo "${{ matrix.value }}"
Innanzitutto, abbiamo bisogno di un job di "setup": lo sfruttiamo per generare un oggetto di tipo JSON che rappresenta, a tutti gli effetti, l'array che verrà poi mandato in input al job che si occuperà di eseguire il loop di operazioni. Può anche essere utilizzato per recuperare l'oggetto da un file, dal network o così via. In questo momento ci serve solamente come esempio per preparare i dati.
Il secondo job invece è quello che si occupa in maniera attiva di leggere il valore derivante dal job precedente, ma poichè è stato generato come un array in formato JSON, sfruttiamo la funzione fromJson per effettuare la conversione ad oggetto che la matrice di GitHub è in grado di capire. La matrice, in questo scenario, è un workaround per permettere l'esecuzione dello stesso job (e quindi non solo uno step, ma anche una sequenza di step, esattamente come nel loop di Azure DevOps) N volte, una per ogni oggetto facente parte dell'array in ingresso.
Nell'esempio precedente, noi siamo solamente andati a stampare il valore sulla console, ma ovviamente questo può essere un qualsiasi step. Successivamente a questo job, potremmo averne altri che continueranno ad eseguire il processo che avevamo iniziato precedentemente. Purtroppo, però, al momento rimane un workaround e, quindi, se abbiamo bisogno di passare valori tra il job prima di setup e quello dopo il loop, avremo bisogno di impostare delle dipendenze e di creare altri valori di output, così che siano leggibili successivamente come se questi facessero parte dello stesso flusso, anche se, di fatto, non è così.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Usare i servizi di Azure OpenAI e ChatGPT in ASP.NET Core con Semantic Kernel
Eseguire i worklow di GitHub su runner potenziati
Cancellare una run di un workflow di GitHub
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Filtrare i dati di una QuickGrid in Blazor con una drop down list
Code scanning e advanced security con Azure DevOps
Effettuare il binding di date in Blazor
Assegnare un valore di default a un parametro di una lambda in C#
Eseguire script pre e post esecuzione di un workflow di GitHub
Sostituire la GitHub Action di login su private registry