Les cas d'utilisation du runner me viennent peu à peu ; c'est l"occasion de déplacer des traitements que j'effectuais sur la machine de développement avec un simple Makefile. La démarche est évidemment plus saine pour obtenir des comportements prédictibles et reproductibles.
J'ai commencé par le blog et le premier besoin évident est la publication de l'image Docker du projet. L'action est déclenchée par le push d'un tag de version (exemple v2.4) et elle va construire l'image décrite par le dockerfile et la publier sur Gitea.
Aparté : il y a un écran de paramétrage dans Gitea qui permet d'associer un paquet à un projet. Cela n'a rien d'obligatoire mais cela permet depuis un projet de visualiser les paquets associés.

Fichier .gitea/workflows/publish.yml
name: Build and publish Docker image
on:
push:
tags:
- 'v*'
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: source.madyanne.fr
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Extract version tag
id: meta
run: echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
source.madyanne.fr/yax/blog:${{ steps.meta.outputs.tag }}
source.madyanne.fr/yax/blog:latest
Le second besoin pour le blog a été d'imaginer une action qui vérifie s'il n'y a pas de lien cassé. On va limiter aux liens internes dans le cas de la publication d'un article avec des erreurs.
La vérification des liens externes est très longue et le résultat n'est pas garanti à cause des protections de site ; cela n'a pas trop de sens de la confier à l'intégration continue car le résultat demande interprétation. J'ai une tâche locale lancée à la demande pour recenser les liens externes déplacés ou supprimés... ce qui est le plus fréquent malheureusement.
La vérification des liens s'appuie sur l'outil Lychee. Le premier workflow basé sur une image alpine installait tous les paquets nécessaires au build du blog et lychee puis il faisait un checkout (git clone) du blog, générait le site statique et lançait lychee sur le site généré. Cela fonctionnait mais cela prenait environ 4 minutes sur mon modeste runner. Le résumé de l'action montrait que l'essentiel du temps était passé sur l'installation des dépendances.
Pour accélérer le processus, une image dédiée à l'intégration continue a été ajoutée au projet : elle contient tous les programmes nécessaires pour construire le blog et exécuter Lychee et elle est publiée par Gitea à chaque modification de son fichier dockerfile Dockerfile.ci :
Fichier .gitea/workflows/build-ci-image.yml
name: Build CI image
on:
push:
paths:
- 'Dockerfile.ci'
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: source.madyanne.fr
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.ci
push: true
tags: source.madyanne.fr/yax/blog-ci:latest
La vérification des liens s'appuie sur cette image blog-ci, elle est lancée à chaque commit Git.
Fichier .gitea/workflows/check-links.yml
name: Check broken links
on:
push:
pull_request:
jobs:
check-links:
runs-on: ubuntu-latest
container:
image: source.madyanne.fr/yax/blog-ci:latest
credentials:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build site
run: bash makesite.sh --local
- name: Check internal links
run: lychee --offline --no-progress --base '_site' --config .lychee.toml '_site/**/*.html'
Le temps moyen d'exécution est de 22 secondes, une belle optimisation en temps mais aussi en ressources processeur / énergie. Les dépendances du blog changent rarement, ça n'avait pas de sens de les installer à chaque exécution. J'apprécie la réflexion constante pour concilier le besoin d'automatisation et les ressources limitées du MiniPC.