Questo documento spiega come impostare i workflow di integrazione continua (CI) per un track di linguaggio di Exercism usando GitHub Actions (GHA). Fornisce buone pratiche ed esempi da usare per creare workflow di CI veloci, affidabili e robusti. I workflow GHA in questa cartella si possono adattare a qualsiasi CI, perché la struttura di base rimane la stessa.
Il documento:
Un esempio di implementazione di questi file di workflow si trova in exercism/javascript.
Il resto del documento serve a spiegare come funzionano i workflow. Se hai fretta e vuoi solo passare da Travis o Circle a GHA senza ottimizzare gli script delle PR, dai un'occhiata alla nostra guida da ~10 minuti su Migrare da Travis.
Le azioni consigliate per verificare che il contenuto del repository sia integro sono le seguenti:
configlet per controllare config.json
v3 richiede nuovi file; questo controllo potrebbe essere spostato in configlet)Ci possono anche essere azioni specifiche del track. Per esempio:
E magari vorrai anche altri controlli di qualità della vita, come:
Per ogni azione, pensa a quanto spesso deve essere eseguita.
configlet è così importante (perché un track può rompersi se si rompe il config.json) che probabilmente dovrebbe essere eseguito sempre, ma deve esserlo solo una volta per commit.Può essere molto utile rendere disponibili in locale anche le azioni che devono essere eseguite. Così anche gli script che fanno il lavoro vero e proprio si possono eseguire manualmente. Per ottenere questo, non inserire inline l'azione nei file di workflow, ma crea uno script autonomo. Per esempio, il controllo degli stub si può scrivere tranquillamente tutto in bash dentro il file di workflow, ma qui la raccomandazione è creare invece un nuovo script eseguibile scripts/ci-check.
«Ma il comando è molto corto, ad esempio
eslint . --ext ts --ext tsx».Quando questo comando deve essere aggiornato, ora va aggiornato in tutti i punti: nella documentazione, nei file di workflow e nella mente dei maintainer. Estrarre tutto questo in uno script risolve il problema. Inoltre, leggere un file di workflow può essere molto scoraggiante.
Gli script scripts/pr e scripts/pr-check (vedi template) vengono eseguiti con diversi argomenti, uno per ogni file modificato o aggiunto in questa PR. Per esempio, se two-fer è stato aggiornato, una chiamata potrebbe essere così:
scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext
Si consiglia di eseguire le azioni sull'esercizio modificato e non sul file modificato. Il motivo è che cambiare un file può facilmente innescare cambiamenti per tutto l'esercizio (pensa a: configurazione, pacchetti).
Non sei pronto? / Troppo complicato?
Prima di implementare questa ottimizzazione, puoi tranquillamente ignorarla! La guida alla migrazione suggerisce di aggiungerla in una fase successiva. Se gli argomenti di input vengono ignorati, tutti i controlli verranno eseguiti su tutti gli esercizi. Va benissimo così. Ci vorrà solo più tempo.
Se il track ha un unico file di dipendenze "di primo livello" e/o altri file di configurazione, aggiungi un passaggio di integrità (che affianca uno scripts/sync o bin/sync, il quale copierebbe tutti i file di configurazione in tutti gli esercizi), che assicura che i file di primo livello o di base siano uguali a quelli copiati nelle cartelle degli esercizi. Così le dipendenze si possono aggiornare e sincronizzare in tutto il repository, e possiamo assicurarci che tutti gli esercizi abbiano la stessa configurazione.
Un modo comune per ottenere questo è usare un checksum. Ubuntu (e varie altre distribuzioni Linux) include uno strumento chiamato sha1sum, ma funzionerebbe qualsiasi metodo per calcolare l'hash o ridurre il file di configurazione (md5, sha1, crc32) a un valore di checksum:
$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md
Se il track usa workflow aggiuntivi che richiedono l'accesso al token di GitHub o ad altri secret, la buona pratica è fissare tutte le azioni usate nel workflow a un commit specifico. Per i dettagli, vedi la guida di GitHub al rafforzamento della sicurezza.
Per esempio:
- uses: julia-actions/setup-julia@v1
+ uses: julia-actions/setup-julia@d26d1111976eae5f00db04f0515ab744ec9cd79e # 1.3.1
Se gli strumenti hanno dei lockfile per la gestione delle dipendenze, valuta di inserirli nel repository e di usare un "lockfile bloccato" nei file di workflow. Per esempio: npm ci, yarn install --frozen-lockfile e bundle install --frozen. Questo assicura che il lockfile sia aggiornato quando cambi le dipendenze e impedisce l'ingresso di pacchetti malevoli.
In questa cartella ci sono come minimo i seguenti template:
configlet.yml: questo workflow scarica l'ultimo binario di configlet e fa il lint di questo repository. Viene eseguito a ogni commit. Per le PR, viene eseguito sul commit effettivo e su un albero "dopo il merge".ci.yml: questo workflow viene eseguito solo sul branch main, una volta per ogni commit.
pr.ci.yml: questo workflow viene eseguito solo sulle PR, una volta per ogni commit.
I workflow non-PR si possono anche attivare tramite workflow_dispatch.
All'inizio di ogni file è indicato quali "script" devono essere disponibili. Se vuoi che siano binari, sostituisci scripts/xxx con bin/xxx. Alcuni strumenti richiedono che i binari stiano dentro una cartella bin.
scripts/ci: uno script che deve fare la build e testare tutti gli esercizi eseguendo le soluzioni di esempio contro i testscripts/ci-check: uno script che deve fare il lint di tutti gli esercizi e, facoltativamente, controllare stub, integrità della configurazione e altro ancorascripts/pr: come scripts/ci, ma deve eseguire solo gli esercizi individuati dai percorsi passati come inputscripts/pr-check: come scripts/ci-check, ma deve essere eseguito solo per i file o gli esercizi individuati dai percorsi passati come inputSe incontri qualche problema o vuoi che qualcuno dia un'occhiata ai tuoi workflow, fai un ping al team @exercism/github-actions.
Hai modificato un file di primo livello che dovrebbe attivare una CI su tutti gli esercizi
Al momento in cui scriviamo,
pr.ci.ymlconsente solo il test per «estensione». L'ideale sarebbe aggiornarlo perché si attivi sempre quando cambiano certi file (per esempio il binario per eseguire i test). Tuttavia, questi cambiamenti sono spesso rari e fatti dai maintainer, quindi il fatto checi.ymlvenga eseguito su main, sempre e per tutto, è probabilmente abbastanza sicuro.
Hai creato un file scripts/xxx su Windows e ora non funziona su {other OS}
Per impostazione predefinita, i file creati su Windows non hanno nel git-index i metadati relativi alla loro eseguibilità, perché il modello dei permessi su Windows è diverso. Git, per impostazione predefinita, usa i metadati del git-index per determinare se il file deve essere eseguibile sui sistemi basati su POSIX, e quindi rende il file
scripts/xxxNON eseguibile.
git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"