Di recente ho costruito un server DNS rudimentale usando Rust per approfondire la mia comprensione dell'argomento. Il progetto, chiamato vòdo, è accessibile qui.
Workflow Quotidiani
A ogni push sul branch main e sulle pull request, voglio compilare il progetto ed eseguire i test per assicurarmi che non vengano introdotti bug. Utilizzo una configurazione di workflow Actions di base per questo scopo:
name: Rust
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verboseQuesta configurazione funziona bene per lo sviluppo quotidiano, ma non è sufficiente per creare una release "di produzione" una volta soddisfatto del risultato. Sebbene esistano Actions sul marketplace che possono generare facilmente una nuova release con artefatti, voglio includere nella release l'eseguibile vòdo per tutti i principali sistemi operativi, il che complica leggermente il processo. Inoltre, la release non deve essere creata se una delle build fallisce.
La Matrix Job Strategy
GitHub Actions offre una funzionalità chiamata "Matrix", che definisce una strategia per i job che consente di usare variabili all'interno di una singola definizione di job per generare automaticamente più esecuzioni del job in base alle combinazioni di variabili. Ad esempio, puoi usare una matrix strategy per testare il tuo codice su varie versioni del linguaggio o su più sistemi operativi. Maggiori dettagli sono disponibili nella documentazione di GitHub.
Questo è l'approccio che ho usato per compilare Vodo per Linux, MacOS e Windows in parallelo. Ho generato un nuovo file di configurazione del workflow Actions specifico per le release. Questo workflow viene attivato dai nuovi tag nel repository, il che significa che per creare una nuova release mi basta generare un nuovo tag Git e farne il push nel repository.
name: Release
on:
push:
tags:
- "*"
jobs:
release:
strategy:
matrix:
include:
- os: ubuntu-latest
artifact_name: ${{ github.event.repository.name }}
asset_name: ${{ github.event.repository.name }}-linux-amd64
- os: windows-latest
artifact_name: ${{ github.event.repository.name }}.exe
asset_name: ${{ github.event.repository.name }}-windows-amd64.exe
- os: macos-latest
artifact_name: ${{ github.event.repository.name }}
asset_name: ${{ github.event.repository.name }}-macos-amd64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Build release
run: >-
cargo build --releaseCon questa configurazione, Actions esegue più job in parallelo, uno per ogni sistema operativo:
Il job in esecuzione su
ubuntu-latestcrea un eseguibile per Linux chiamatovodo-linux-amd64Il job in esecuzione su
macos-latestcrea un eseguibile per MacOS chiamatovodo-macos-amd64Il job in esecuzione su
windows-latestcrea un eseguibile per Windows chiamatovodo-windows-amd64
Questo è l'approccio più semplice che risolve il problema: mi ci è voluto un bel po' di tempo per trovare il modo migliore per ottenere questo risultato senza una configurazione del workflow eccessivamente complessa! Nell'interfaccia di GitHub appare così:

Creare la Release
I passaggi precedenti creano solo gli artefatti, ed è necessario un passaggio aggiuntivo per creare una release e allegarvi gli eseguibili. Questo passaggio usa svenstaro/upload-release-action@v2 ed è eseguito in ogni build specifica per OS. Tuttavia, la release viene creata una sola volta e, se una delle build fallisce, la release viene rimossa. La configurazione necessaria è la seguente:
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: target/release/${{ matrix.artifact_name }}
asset_name: ${{ matrix.asset_name }}
tag: ${{ github.ref }}Al termine di questo passaggio, la release corrispondente al tag viene creata ed è accessibile tramite l'interfaccia utente di GitHub 🎉.

Riepilogo
In questo articolo ho spiegato come ho costruito un server DNS rudimentale chiamato vòdo usando Rust e configurato un workflow GitHub Actions per compilare e testare il progetto. Ho discusso dell'uso della Matrix job strategy per creare build di produzione per più sistemi operativi e di come creare una release con eseguibili allegati usando svenstaro/upload-release-action. Il risultato è un processo di release efficiente e automatizzato per il progetto, con un file di configurazione del workflow facile da comprendere.
lucavallin

