Effettuare un loop di una GitHub Action

di Matteo Tumiati, in DevOps,

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

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