Tre meccanismi, tre momenti diversi
Starter workflow, reusable workflow e composite action risolvono la stessa esigenza — non riscrivere la medesima automazione in ogni repository — ma intervengono in momenti diversi: uno quando il file viene creato, uno quando il job parte, uno dentro il job. Tenere fermo questo asse è il modo più rapido per rispondere alle domande che l’esame dedica al tema, e sono almeno due.
Il template si copia, e da lì diverge
Nella documentazione attuale il termine ufficiale è workflow template; “starter workflow” resta il nome storico e sopravvive nel repository pubblico actions/starter-workflows. Un template è uno scheletro che si copia nel repository di destinazione: dalla tab Actions la pagina Choose a workflow elenca i template disponibili, si preme Configure, si adatta il file e si committa sotto .github/workflows/. Da quel momento la copia è tua: se l’originale viene corretto, il tuo file non cambia. La divergenza è una caratteristica del meccanismo, non un difetto, ed è la ragione per cui un template non è uno strumento di governance.
I template di organizzazione non pubblici vivono in un posto solo: il repository .github dell’organizzazione, cartella workflow-templates/. Ogni template richiede due file con lo stesso nome di base: il .yml del workflow e un .properties.json con almeno name e description — facoltativi iconName, categories e filePatterns. Nel YAML si può usare il segnaposto $default-branch, sostituito con il ramo predefinito del repository che adotta il template. La visibilità del repository .github decide chi li vede: pubblico li rende disponibili a tutti i repository, interno a quelli interni e privati, privato solo a quelli privati, e in quest’ultimo caso va concesso l’accesso in lettura agli utenti o ai team interessati. Un template che “non compare” è quasi sempre un problema di visibilità del .github, non di sintassi.
Il reusable workflow si chiama, la composite action si incorpora
Un reusable workflow non si copia: si invoca. Vive in .github/workflows del repository che lo ospita, espone il trigger workflow_call e si richiama con jobs.<job_id>.uses, cioè a livello di job e mai da uno step. Resta centrale e versionato: il riferimento può essere uno SHA (la forma più stabile), un tag di release o un ramo, e una correzione fatta al centro si propaga a chiunque punti a quel riferimento.
jobs:
build:
uses: my-org/ci-workflows/.github/workflows/build.yml@v2
with:
node-version: '20'
secrets: inherit
Dettagli che ricorrono nelle domande: il workflow chiamato può contenere più job, ciascuno con il proprio log separato; i segreti si passano per nome oppure con secrets: inherit, e nelle catene annidate ogni livello riceve solo ciò che il chiamante diretto gli inoltra; il contesto env del chiamante non arriva al chiamato, quindi per scambiare valori si usano inputs e outputs; i permessi del GITHUB_TOKEN possono essere mantenuti o ridotti lungo la catena, mai innalzati. Esistono inoltre limiti documentati sulla profondità di annidamento e sul numero di reusable workflow distinti richiamabili da un singolo file: vale la pena rileggerli nella pagina dei limiti. Infine, un reusable workflow non si pubblica sul GitHub Marketplace.
Una composite action è invece un pacchetto di step. Il file di metadati si chiama action.yml o action.yaml, dichiara runs.using: composite e una lista di steps in cui ogni run deve specificare la propria shell. Si consuma con uses dentro uno step — un riferimento tipo my-org/setup-tools@v1 oppure un percorso locale come ./.github/actions/setup-tools — e nel log compare come un unico step consolidato. Non ha runs-on, non definisce job propri e non accede direttamente ai segreti: i valori sensibili vanno passati come inputs dal workflow chiamante. In compenso, a differenza del reusable workflow, può essere pubblicata sul Marketplace.
Per condividere action e reusable workflow ospitati in un repository privato si usa Settings > Actions > General, sezione Access, scegliendo l’opzione che li rende accessibili dai repository dell’organizzazione. Attenzione al risvolto di sicurezza segnalato dalla documentazione: chi legge i log dei run può vedere indirettamente contenuti del repository privato pur non avendovi accesso.
Disabilitare non è eliminare
Disable workflow si trova nella tab Actions, selezionando il workflow nella barra laterale e aprendo il menu con i tre puntini. Il file YAML resta nel repository, la cronologia dei run resta consultabile e il workflow semplicemente non viene più innescato; si riattiva con Enable workflow. Da riga di comando: gh workflow disable e gh workflow enable. Alcuni casi di disattivazione avvengono da soli: i workflow schedulati nei repository pubblici vengono disabilitati dopo un lungo periodo senza attività del repository, e i fork di repository pubblici nascono con i workflow disattivati.
Eliminare un workflow è un’altra cosa: non esiste un comando dedicato, si cancella il file dal repository e la definizione sparisce. Diverso ancora è Delete workflow run, che rimuove in modo permanente una singola esecuzione e richiede accesso in scrittura e un run già concluso.
L’esame verifica proprio questa terna di scelte: scaffolding iniziale che poi ogni team fa suo (template), logica centralizzata e versionata che deve restare una sola (reusable workflow), sequenza di comandi ripetuta dentro un job (composite action). E controlla che tu sappia fermare un workflow senza toccare il codice: la risposta è disabilitarlo, non cancellare il file né i run.