Ho una lunga esperienza con i flussi di lavoro di GitHub, ma non fino al punto in cui posso affermare di essere un esperto.Tuttavia, ho recentemente sviluppato un nuovo flusso di lavoro, e mi ha spinto a scrivere questo post. Quali sono i flussi di lavoro GitHub? Un flusso di lavoro è un processo automatizzato configurabile che esegue una o più attività. I flussi di lavoro sono definiti da un file YAML che viene visualizzato nel repository e vengono eseguiti quando sono attivati da un evento nel repository, oppure possono essere attivati manualmente o su un programma definito. I flussi di lavoro sono definiti nella directory .github/workflows in un repository. Un repository può avere più flussi di lavoro, ognuno dei quali può eseguire un set diverso di attività, come ad esempio: Costruire e testare le richieste di pull Implementare l'applicazione ogni volta che viene creata una release Aggiungere un'etichetta ogni volta che viene aperto un nuovo problema - sui flussi di lavoro Un flusso di lavoro è un processo automatizzato configurabile che esegue una o più attività. I flussi di lavoro sono definiti da un file YAML che viene visualizzato nel repository e vengono eseguiti quando sono attivati da un evento nel repository, oppure possono essere attivati manualmente o su un programma definito. I flussi di lavoro sono definiti nel Un repository può avere più flussi di lavoro, ognuno dei quali può eseguire un diverso insieme di attività, come ad esempio: .github/workflows Costruire e testare le richieste di pull Implementare l'applicazione ogni volta che viene creata una release Aggiungere un'etichetta ogni volta che viene aperto un nuovo problema - sui flussi di lavoro Come tale, un flusso di lavoro è paragonabile a un lavoro Jenkins, implementato in YAML invece di XML. Non sembra molto, ma consente l'uso di approcci di gestione del codice sorgente, tra cui la versione e il rolling back. Anni fa, ho lavorato per un cliente il cui team di DevOps ha implementato un approccio basato su Puppet per ricostruire i lavori di Jenkins in modo che la configurazione Puppet possa essere memorizzata in Git. stored inside the code repository Nota che GitHub era abbastanza tardi per la festa. Prima di implementare i flussi di lavoro, ho usato un servizio di terze parti chiamato Ho cambiato principalmente perché Travis è diventato pagato e secondariamente perché i flussi di lavoro sono parte nativa di GitHub. Travis ci Questo Tip: Sono chiamati Le azioni di GitHub sono completamente diverse. Use the correct semantics Flussi di lavoro GitHub Azioni di GitHub I flussi di lavoro GitHub sono costituiti da che si compongono di Passo di riferimento comandi, e un paio di parametri opzionali, tra cui un nome. Lavori passaggi corsa jobs: metrics: runs-on: my-image #1 steps: - name: Install dependencies via Poetry #2 run: poetry install #3 Immagine OCI su cui viene eseguito il workflow Nome passo comando passo Le azioni GitHub sono componenti riutilizzabili che offrono alternative alla ripetizione dello stesso comando ancora e ancora. Un'azione è un insieme di attività o di codice predefinito e riutilizzabile che esegue attività specifiche all'interno di un flusso di lavoro, riducendo la quantità di codice ripetitivo che si scrive nei file del flusso di lavoro. Pulling your Git repository from GitHub Impostare la corretta toolchain per il tuo ambiente di costruzione Configurare l'autenticazione per il tuo provider cloud Puoi scrivere le tue azioni, o puoi trovare azioni da utilizzare nei tuoi flussi di lavoro nel Marketplace di GitHub. Ad esempio, invece di eseguire il check-out di git, puoi utilizzare l'azione di check-out. GitHub azione Un'azione è un insieme di attività o di codice predefinito e riutilizzabile che esegue attività specifiche all'interno di un flusso di lavoro, riducendo la quantità di codice ripetitivo che si scrive nei file del flusso di lavoro. Togliere il tuo repository Git da GitHub Impostare la corretta toolchain per il tuo ambiente di costruzione Configurare l'autenticazione per il tuo provider cloud Puoi scrivere le tue azioni, o puoi trovare azioni da utilizzare nei tuoi flussi di lavoro nel Marketplace di GitHub. Ad esempio, invece di eseguire il check-out di git, puoi utilizzare l'azione di check-out. GitHub azione jobs: metrics: runs-on: my-image steps: - uses: actions/checkout@v5 #1 with: #2 fetch-depth: 0 submodules: recursive Riferimento a un'azione GitHub Parametri di azione Sono un grande fan di non reinventare la ruota.GitHub Actions gioca un ruolo importante in questo. Questo Tip: Quando possibile Prefer GitHub Actions over ad-hoc commands Scegliere l’azione giusta Il mercato di GitHub Le azioni sono elencate per categoria. È possibile filtrare per tipo di creatore e ordinare per popolarità. Molte azioni Quando si sceglie un'azione, si dovrebbe esercitare la stessa attenzione come quando si porta in qualsiasi altra dipendenza. Ecco alcuni criteri per aiutarti: Vendor: prefer verified creators License type: Open Source vs. closed source. With the former, check the exact terms; the Apache v2 license is very different from the GPL one. Pricing for commercial actions Check the source code repository of actions that display it and check the following information: ** Inception date ** Activity, including the repartition of commits per committer, the number of open issues, the mean time for fixing issues, etc. ** Documentation (reference material, tutorials, how-to guides, and explanations) Community, if any Support Questo Tip: Be as careful in choosing a GitHub Action as in choosing any other dependency. Conosci le tue azioni Come il suggerimento precedente, questo deriva da uno più generico - parlo dall'esperienza. stavo sviluppando un flusso di lavoro per imballare un'applicazione Java. stavo usando pesantemente il flusso di lavoro, e il lavoro doveva scaricare le dipendenze a ogni esecuzione. jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-java@v4 #1 with: distribution: temurin java-version: 21 - uses: actions/cache@v4 #2 with: path: ~/.m2/repository #3 key: ${{ platform }}-maven--${{ hashFiles('**/pom.xml') }} #4 restore-keys: | ${{ runner.os }}-maven- #4 Installazione JDK Impostare una cache. La cache è generica e può catturare i file attraverso le esecuzioni. Cache il repository Maven locale La chiave utilizza il runner OS, che non cambia, e il hash del POM. Pertanto, il passaggio crea una nuova cache ogni volta che il POM cambia. Tuttavia, leggendo la documentazione, mi sono reso conto che potevo raggiungere lo stesso in un modo molto più semplice: L'azione ha una funzionalità integrata per la cache e il ripristino delle dipendenze. Utilizza il toolkit/cache sotto cappello per la cache delle dipendenze, ma richiede meno impostazioni di configurazione. I gestori di pacchetti supportati sono gradle, maven e sbt. Il formato della chiave cache utilizzata è setup-java-${plattform }}-${ packageManager }}-${ fileHash }}, dove il hash è basato sui seguenti file: MAVEN: */pom.xml Caching dipendenze pacchetti L'azione ha una funzionalità incorporata per la cache e il ripristino delle dipendenze. Utilizza toolkit/cache sotto cappello per la cache delle dipendenze ma richiede meno impostazioni di configurazione. I gestori di pacchetti supportati sono gradle, maven e sbt. Il formato della chiave cache utilizzata è , dove il hash è basato sui seguenti file: setup-java-${{ platform }}-${{ packageManager }}-${{ fileHash }} MAVEN: */pom.xml Caching dipendenze pacchetti Così ho sostituito il passaggio sopra riportato con il seguente: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-java@v4 with: distribution: temurin java-version: 21 cache: maven #1 Questo è il Questo Tip: Trascorrere un'ora sulla documentazione può aiutarti a risparmiare giorni di sforzo. Thoroughly read the documentation of actions. Pin la tua versione di dipendenza Questa sezione prende anche consigli generici e lo applica alla versione dei flussi di lavoro di GitHub. Troverete versioni in almeno due luoghi: l'immagine OCI e la versione di GitHub Actions. Potresti aver notato il in questi precedenti articoli, al momento della scrittura, si riferisce al Con il passare del tempo, indica l'ultima versione, con le versioni di diverse librerie. Può causare un guasto durante l'esecuzione del flusso di lavoro, o peggio, modificare l'uscita in modi che non noteresti fino a quando non sarà troppo tardi. [Tutte le immagini disponibili] runs-on: ubuntu-latest ubuntu-24.04 https://github.com/actions/runner-images La versione delle azioni funziona in modo diverso, poiché indica il riferimento di un repo GitHub: un tag o un commit SHA. Mentre l'immagine OCI è nelle mani di GitHub, l'azione è responsabilità del suo fornitore. Significa che chiunque abbia i diritti di commit può cambiare il contenuto di un tag sottostante. Pin a un commento. must jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903 #1 Pin per un commit specifico 💡 Suggerimento: prendi la sicurezza sul serio e pin actions to a specific commit. Usare il riassunto del lavoro Ciascuna delle fasi del flusso di lavoro produce probabilmente un sacco di log. In un flusso di lavoro regolare, la quantità complessiva di linee di log può essere abbastanza grande. Alcune di esse potrebbero essere utili, alcune potrebbero non essere, ma perché c'è solo una uscita standard e un errore standard, tutto finisce nello stesso luogo. , il numero di test eseguiti o la percentuale di copertura del codice, nel caso in cui non invii questi dati altrove. GitHub rende semplice aggiungere i dati che desideri nel riassunto del lavoro. di G. È possibile impostare un Markdown personalizzato per ciascun lavoro in modo che venga visualizzato sulla pagina di sintesi di un esecuzione del flusso di lavoro. È possibile utilizzare le sintesi del lavoro per visualizzare e raggruppare contenuti unici, ad esempio le sintesi dei risultati del test, in modo che qualcuno che visualizza il risultato di un esecuzione del flusso di lavoro non abbia bisogno di accedere ai log per visualizzare informazioni importanti relative all'esecuzione, ad esempio i fallimenti. I riassunti del lavoro supportano il Markdown aromatizzato da GitHub, e puoi aggiungere il tuo contenuto di Markdown per un passo al file ambientale GITHUB_STEP_SUMMARY. Aggiungere un riassunto del lavoro È possibile impostare un Markdown personalizzato per ciascun lavoro in modo che venga visualizzato sulla pagina di sintesi di un esecuzione del flusso di lavoro. È possibile utilizzare le sintesi del lavoro per visualizzare e raggruppare contenuti unici, ad esempio le sintesi dei risultati del test, in modo che qualcuno che visualizza il risultato di un esecuzione del flusso di lavoro non abbia bisogno di accedere ai log per visualizzare informazioni importanti relative all'esecuzione, ad esempio i fallimenti. I riassunti del lavoro supportano il Markdown aromatizzato da GitHub, e puoi aggiungere il tuo contenuto di Markdown per un passo al Il file ambientale. è unico per ogni passo di un lavoro. GITHUB_STEP_SUMMARY GITHUB_STEP_SUMMARY - di Aggiungere un riassunto del lavoro Ecco a di Apache Arrow: Il campione - name: Show inputs run: | echo "upload_artifacts: ${{ inputs.upload_artifacts }}" >> $GITHUB_STEP_SUMMARY echo "schedule: ${{ github.event.schedule }}" >> $GITHUB_STEP_SUMMARY echo "ref: ${{ github.ref }}" >> $GITHUB_STEP_SUMMARY Il è : Risultato Questo Tip: Migliorare l’esperienza dello sviluppatore. Use GitHub job summary Comprendere il ciclo di vita dei flussi di lavoro I flussi di lavoro eseguono i passaggi in sequenza. Un passo fallito cancella tutti i passaggi rimanenti e il flusso di lavoro finisce in un Nell'esempio di cui sopra, significa che non riceveremo alcun riassunto di test se uno dei passaggi successivi fallisce. delle condizioni. Failure if È possibile utilizzare le seguenti funzioni di controllo di stato come espressioni in if condizionali. Un controllo di stato predefinito di successo() viene applicato a meno che non si includa una di queste funzioni. - Funzioni di controllo dello stato È possibile utilizzare le seguenti funzioni di controllo di stato come espressioni in if condizionali. Un controllo di stato predefinito di successo() viene applicato a meno che non si includa una di queste funzioni. - Funzioni di controllo dello stato Github utilizza per impostazione predefinita, ma le opzioni includono di , e . success() always() cancelled() failure() - name: Show inputs if: ${{ always() }} #1 run: | echo "upload_artifacts: ${{ inputs.upload_artifacts }}" >> $GITHUB_STEP_SUMMARY echo "schedule: ${{ github.event.schedule }}" >> $GITHUB_STEP_SUMMARY echo "ref: ${{ github.ref }}" >> $GITHUB_STEP_SUMMARY Eseguire sempre il passaggio, indipendentemente dal fatto che i passaggi precedenti abbiano avuto successo o meno. Immaginate la seguente sequenza: - name: Step that may fail run: whatever - name: Execute unit tests run: ./mvnw -B test #1 - name: Test Summary if: ${{ always() }} uses: test-summary/action@31493c7 #2 Test di unità in esecuzione generano anche rapporti JUnit Utilizzare i rapporti JUnit generati per scrivere un riassunto dei passaggi Se il primo passo fallisce, il riepilogo viene eseguito indipendentemente dal fatto che i test siano stati eseguiti. Se non fossero stati eseguiti, fallirà. Per evitare questo, dobbiamo perfezionare ulteriormente la condizione in modo che il riepilogo venga eseguito solo se il passo di prova dell'unità lo ha fatto. - name: Step that may fail run: whatever - name: Execute unit tests id: test #1 run: ./mvnw -B test - name: Test Summary if: ${{ always() && steps.test.conclusion == 'success'}} #2 uses: test-summary/action@31493c7 Impostare l'ID del passaggio Eseguire solo se la fase di prova è stata eseguita con successo È solo un semplice esempio, ma offre opzioni interessanti. Questo Tip: Usalo a tuo vantaggio. Know workflows' lifecycle Testato localmente Molte organizzazioni applicano rigide regole GitHub. La più diffusa è che non puoi spingere a : ogni commit deve passare attraverso una richiesta di pull. Mentre ha senso per i progetti stabiliti, impedisce che i progetti iniziino a iterarsi rapidamente mantenendo la cronologia del commit. Nel contesto dello sviluppo dei flussi di lavoro GitHub, è sicuramente crippling. master Viene presentato il progetto di atto: “Pensire globalmente, agire localmente” Esegui le tue azioni GitHub localmente! Perché vorresti farlo? due motivi: - Rather than having to commit/push every time you want to test out the changes you are making to your files (or for any changes to embedded GitHub actions), you can use act to run the actions locally. The environment variables and filesystem are all configured to match what GitHub provides. Fast Feedback .github/workflows/ Local Task Runner - Amo fare. Tuttavia, odio anche ripetere me stesso. Con l'azione, puoi usare le azioni GitHub definite nel tuo .github/workflows/ per sostituire il tuo Makefile! - Introduzione all'azione “Pensire globalmente, agire localmente” Esegui le tue azioni GitHub localmente! Perché vorresti farlo? due motivi: Rapido feedback - Piuttosto che dover impegnarsi / spingere ogni volta che si desidera testare le modifiche che si stanno apportando ai file .github / workflows / (o per eventuali modifiche alle azioni GitHub incorporate), è possibile utilizzare l'azione per eseguire le azioni localmente. le variabili ambientali e il file system sono tutti configurati per corrispondere a ciò che GitHub fornisce. Local Task Runner - Amo fare. Tuttavia, odio anche ripetere me stesso. Con l'azione, puoi usare le azioni GitHub definite nel tuo .github/workflows/ per sostituire il tuo Makefile! - Introduzione all'azione ha un'integrazione GitHub CLI che attiva il flusso di lavoro in base all'evento corretto. act gh act push Ecco le uscite quando le immagini e le azioni sono già state scaricate: INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock' [workflow.yml/test] ⭐ Run Set up job [workflow.yml/test] 🚀 Start image=catthehacker/ubuntu:act-22.04 [workflow.yml/test] 🐳 docker pull image=catthehacker/ubuntu:act-22.04 platform= username= forcePull=true [workflow.yml/test] 🐳 docker create image=catthehacker/ubuntu:act-22.04 platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host" [workflow.yml/test] 🐳 docker run image=catthehacker/ubuntu:act-22.04 platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host" [workflow.yml/test] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir= [workflow.yml/test] ✅ Success - Set up job [workflow.yml/test] ☁ git clone 'https://github.com/actions/setup-java' # ref=v4 [workflow.yml/test] ⭐ Run Main actions/checkout@v4 [workflow.yml/test] 🐳 docker cp src=/Users/nico/projects/act-sample/. dst=/Users/nico/projects/act-sample [workflow.yml/test] ✅ Success - Main actions/checkout@v4 [9.211777902s] [workflow.yml/test] ⭐ Run Main Setup JDK [workflow.yml/test] 🐳 docker cp src=/home/nico/.cache/act/actions-setup-java@v4/ dst=/var/run/act/actions/actions-setup-java@v4/ [workflow.yml/test] 🐳 docker exec cmd=[/opt/acttoolcache/node/18.20.8/x64/bin/node /var/run/act/actions/actions-setup-java@v4/dist/setup/index.js] user= workdir= [workflow.yml/test] ❓ ::group::Installed distributions | Resolved Java 21.0.8+9.0.LTS from tool-cache | Setting Java 21.0.8+9.0.LTS as the default | Creating toolchains.xml for JDK version 21 from temurin | Writing to /root/.m2/toolchains.xml | | Java configuration: | Distribution: temurin | Version: 21.0.8+9.0.LTS | Path: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.8-9.0.LTS/x64 | [workflow.yml/test] ❓ ::endgroup:: [workflow.yml/test] ❓ add-matcher /run/act/actions/actions-setup-java@v4/.github/java.json | Creating settings.xml with server-id: github | Writing to /root/.m2/settings.xml [workflow.yml/test] ⚙ *** | Cache Size: ~50 MB (52710428 B) | [command]/usr/bin/tar -xf /tmp/c8ef4803-85c1-4867-ac2d-442dbce79755/cache.tzst -P -C /Users/nico/projects/act-sample --use-compress-program unzstd | Cache restored successfully | Cache restored from key: setup-java-linux-x64-maven-ef0e54e9035c18b60db7ea0af5e2f0c4cc5445dd6a2a2a672b91e14f14e7e4c2 [workflow.yml/test] ✅ Success - Main Setup JDK [2.514565962s] [workflow.yml/test] ⚙ ::set-env:: JAVA_HOME=/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.8-9.0.LTS/x64 [workflow.yml/test] ⚙ ::set-env:: JAVA_HOME_21_X64=/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.8-9.0.LTS/x64 [workflow.yml/test] ⚙ ::set-output:: distribution=Temurin-Hotspot [workflow.yml/test] ⚙ ::set-output:: path=/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.8-9.0.LTS/x64 [workflow.yml/test] ⚙ ::set-output:: version=21.0.8+9.0.LTS [workflow.yml/test] ⚙ ::set-output:: cache-hit=false [workflow.yml/test] ⚙ ::add-path:: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.8-9.0.LTS/x64/bin [workflow.yml/test] ⭐ Run Main Run "fast" tests [workflow.yml/test] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/2] user= workdir= | [INFO] Scanning for projects... | [INFO] | [INFO] ----< ch.frankel.blog:act-sample >----- | [INFO] Building act-sample 1.0-SNAPSHOT | [INFO] from pom.xml | [INFO] ------------------------[ jar ]------------------------- | [INFO] | [INFO] --- resources:3.3.1:resources (default-resources) @ act-sample --- | [INFO] Copying 1 resource from src/main/resources to target/classes | [INFO] | [INFO] --- compiler:3.14.0:compile (default-compile) @ act-sample --- | [INFO] Recompiling the module because of changed source code. | [INFO] Compiling 5 source files with javac [debug target 21] to target/classes | [INFO] | [INFO] --- resources:3.3.1:testResources (default-testResources) @ act-sample --- | [INFO] Copying 2 resources from src/test/resources to target/test-classes | [INFO] | [INFO] --- compiler:3.14.0:testCompile (default-testCompile) @ act-sample --- | [INFO] Recompiling the module because of changed dependency. | [INFO] Compiling 1 source file with javac [debug target 21] to target/test-classes | [INFO] | [INFO] --- surefire:3.2.5:test (default-test) @ act-sample --- | [INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider | [INFO] | [INFO] ------------------------------------------ | [INFO] T E S T S | [INFO] ------------------------------------------ | [INFO] Running ch.frankel.blog.ActSampleTest | [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.120 s -- in ch.frankel.blog.ActSampleTest | [INFO] | [INFO] Results: | [INFO] | [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 | [INFO] | [INFO] ------------------------------------------------------ | [INFO] BUILD SUCCESS | [INFO] ------------------------------------------------------ | [INFO] Total time: 3.318 s | [INFO] Finished at: 2025-08-22T10:26:29Z | [INFO] ------------------------------------------------------ [workflow.yml/test] ✅ Success - Main Run "fast" tests [20.920776212s] [workflow.yml/test] ⭐ Run Post Setup JDK [workflow.yml/test] 🐳 docker exec cmd=[/opt/acttoolcache/node/18.20.8/x64/bin/node /var/run/act/actions/actions-setup-java@v4/dist/cleanup/index.js] user= workdir= | [command]/usr/bin/tar --posix -cf cache.tzst --exclude cache.tzst -P -C /Users/nico/projects/act-sample --files-from manifest.txt --use-compress-program zstdmt | Cache Size: ~50 MB (52701753 B) | Cache saved successfully | Cache saved with the key: setup-java-Linux-x64-maven-ef0e54e9035c18b60db7ea0af5e2f0c4cc5445dd6a2a2a672b91e14f14e7e4c2 [workflow.yml/test] ✅ Success - Post Setup JDK [1.01412383s] [workflow.yml/test] ⭐ Run Complete job [workflow.yml/test] Cleaning up container for job test [workflow.yml/test] ✅ Success - Complete job [workflow.yml/test] 🏁 Job succeeded Potrei scrivere un paio di post su Vi lascio a leggere la documentazione. act Questo Tip: Riduci il tuo ciclo di feedback. Test your workflows locally riassunto Utilizzare la semantica corretta, distinguere tra flussi di lavoro e azioni. Preferisco GitHub Actions rispetto ai comandi ad hoc. Essere altrettanto attenti nella scelta di un'azione GitHub come nella scelta di qualsiasi altra dipendenza. Leggi attentamente la documentazione di ogni azione che usi. Pin azioni per un commit specifico. Utilizzare il riassunto del lavoro di GitHub per migliorare l'esperienza dello sviluppatore. Conoscere il ciclo di vita dei workflows. Prova i tuoi flussi di lavoro localmente. To go further: I flussi di lavoro GitHub azione GitHub Marketplace di azione Immagini di Runner Aggiungere un riassunto del lavoro Funzioni di controllo dello stato Introduzione all’atto