Accès aux exemples
Les exemples présentés sont accessibles directement sur le dépôt git associé : https://github.com/conception-logicielle-ensai/exemples-cours/tree/main/architecture-applicative
Automatisation des contrôles en local#
Qu’est-ce qu’un git hooks ?#
Les hooks Git sont des scripts qui s’exécutent automatiquement dès qu’un événement particulier se produit dans un dépôt Git. Ils vous permettent de personnaliser le comportement interne de Git et de déclencher des actions personnalisables à des points clés dans le cycle de vie du développement.
Création d’un hook#
Nous souhaitons automatiser le formatage du code ainsi que la correction des avertissements issus de l’analyse statique (linter) pour les fichiers inclus dans notre prochain commit. Pour ce faire, nous allons mettre en place un hook Git chargé d’effectuer l’auto-formatage et la validation du code au moment du commit.
En supposant que vous ayez installé les packages nécessaires, sinon, tapez la commande suivante :
# Commande pour installer ruff
uv add --dev ruff
uv syncPour utiliser ruff, il vous suffit de taper les commandes suivantes à la racine de votre projet :
# Corriger automatiquement les problèmes simples
uv run ruff check --fix
# Appliquer le formatage automatique
uv run ruff format
# Afficher les problèmes détectés
uv run ruff check
# Vérifier que le code respecte les règles de formatage
uv run ruff format --checkPour cela, nous allons créer un fichier pre-commit personnalisé directement dans le dossier .git/hooks de votre projet.
Voici un lien vers un tutoriel qui explique comment créer un git hook.
TP création d’un hook pre-commit#
Pour ce TP, nous allons nous concentrer sur l’utilisation de la ligne de commande.
0. Observer le dossier .git#
Nous allons parcourir le dossier .git, qui contient des informations cruciales sur la gestion des versions de notre projet. Pour cela, nous utiliserons les commandes suivantes :
# Se déplacer dans le répertoire du projet
cd chemin/vers/ton/projet
# Afficher le contenu du dossier .git
ls -la .git
# Entrer dans le dossier .git
cd .git
# Voir le contenu du dossier .git
ls
# Accéder au dossier objects
cd objects
# Afficher le contenu du dossier objects
ls
# Revenir au dossier .git
cd ..
# Revenir au dossier parent du projet
cd ..
ls: Affiche la liste des fichiers et des répertoires.-l: Affiche les détails sous forme de liste (permissions, propriétaire, taille, etc.).-a: Affiche tous les fichiers, y compris ceux qui commencent par un point (.), qui sont normalement cachés.
cd: Permet de changer de dossier.
Sous-dossiers importants dans .git
Voici quelques exemples de sous-dossiers essentiels que vous pouvez trouver dans .git :
objects: Contient les objets Git (commits, arbres, blobs).refs: Contient les références aux branches et aux tags.config: Fichier de configuration du dépôt Git.
1. Créer ou modifier le fichier pre-commit#
Accédez au dossier .git/hooks de votre projet et créez un fichier nommé pre-commit :
touch .git/hooks/pre-commit
touchest utilisée pour créer des fichiers vides
2. Ajouter du contenu au fichier pre-commit#
Ouvrez ce fichier dans un éditeur de texte :
nano .git/hooks/pre-commit
nanoest un éditeur de texte en ligne de commande.
Ajoutez le script suivant :
#!/bin/bash
set -e
echo "=== Hook pre-commit ==="
# Tous les fichiers du staging (sauf suppressions)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=d | grep '\.py$' || true)
if [ -z "$STAGED_FILES" ]; then
echo "Aucun fichier à analyser."
exit 0
fi
echo "Fichiers analysés :"
echo "$STAGED_FILES"
echo
# ---------------------------------------------------
# Étape 1 — Formatage automatique
# ---------------------------------------------------
echo "[1/2] Formatage automatique (ruff format)"
if uv run ruff format $STAGED_FILES; then
echo "Formatage terminé avec succès."
else
echo "Erreur lors du formatage."
echo "Le commit est bloqué."
exit 1
fi
echo
# ---------------------------------------------------
# Étape 2 — Corrections automatiques
# ---------------------------------------------------
echo "[2/2] Corrections automatiques (ruff check --fix)"
if uv run ruff check --fix $STAGED_FILES; then
echo "Corrections automatiques appliquées."
else
echo "Certaines règles Ruff ne peuvent pas être corrigées automatiquement."
echo "Des erreurs Ruff nécessitent une correction manuelle."
echo "Le commit est bloqué."
exit 1
fi
echo
# ---------------------------------------------------
# Mise à jour du staging
# ---------------------------------------------------
echo "Mise à jour du staging..."
git add $STAGED_FILES
echo "Toutes les vérifications Ruff sont passées."
echo "Commit autorisé."
exit 0
$(...)est utilisé pour exécuter une commande et insérer son résultat dans une autre commande ou une variable.
echoest utilisée pour afficher du texte ou des variables dans le terminal.
3. Rendre le fichier exécutable#
Rendez le fichier pre-commit exécutable avec la commande suivante :
chmod +x .git/hooks/pre-commit
chmod(abréviation de Change Mode) est utilisée en ligne de commande pour modifier les permissions d’accès à des fichiers ou des répertoires
4. Tester le hook#
Essayez de committer un fichier dans votre projet pour voir si le hook est exécuté :
git add .
git commit -m "Test du hook pre-commit"Si des fichiers sont modifiés par ruff, le hook les ajoutera automatiquement au staging et réexécutera les étapes.
Points importants#
Si un fichier ne respecte pas les règles, ruff bloquera le commit. Vous devrez corriger les erreurs avant de réessayer.
Automatisation des contrôles sur des dépots hébergés#
Les Forges Logicielles : Gitlab, Github (etc …) proposent une infrastructure de runners et executeurs qui permettent d’éxecuter des traitements lors d’événements liés a la mise a jour, publication ou autre de votre code.
L’un des principaux usages de ces fonctionnalité, c’est de faire tourner des vérifications statiques et dynamiques de votre code. Ainsi, vous n’avez plus a penser a vos contrôles, ils s’executent a chaque nouveau commit par exemple et donc cela vous permet de voir apparaître les bugs, les régression et d’avoir des arguments objectifs pour la validation ou le rejet d’ajout du code d’un collègue.
Cela permet également l’hébergement de pages web construites (comme ce site web par exemple 🔥).
Github Actions, une introduction#

GitHub Actions est un outil d’intégration et de déploiement continu (CI/CD) natif à GitHub, qui permet d’automatiser des workflows directement dans vos dépôts. Il repose sur trois concepts principaux :
les Workflows : Définissent une suite d’actions à exécuter. Ils sont configurés via des fichiers YAML placés dans le dossier
.github/workflows/du projet sur github.les Jobs : Chaque workflow est composé de jobs qui s’exécutent dans des environnements distincts.
les Steps : Un job est lui-même décomposé en une séquence d’étapes, comprenant des actions prédéfinies ou personnalisées.
Les traitements sont executés sur des machines fournies par github, vous pouvez voir la typologie des machines ici : https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for--private-repositories
Dans le TP d’aujourd’hui et dans vos projets on privilégiera d’utiliser une machine qui est un
ubuntu-22.04comme votre environnement personnel.
Le format des workflow est en YAML, c’est un format de fichier comme le JSON, le XML ou le CSV. On le retrouve spécifiquement pour la configuration de fichier d’intégration et de configuration car il est assez léger a la lecture : il repose comme le python sur de l’indentation.
Exemple avec un yaml “de base”.
name: Simple Python Workflow
on: [push]
jobs:
simple-check:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Run a simple Python command
run: python --versionLe principe est le suivant :
- D’une machine nue on peut executer des commandes pour lui installer ou bien lancer des commandes a partir de ce qui est déjà installé sur la machine.
Avec en plus : des jobs déjà construits par d’autres personnes c’est ce que l’on voit dans actions/checkout@v4 actions/setup-python@v5
On peut voir le code source ici pour le `actions/setup-python par exemple ici : https://github.com/actions/setup-python => https://github.com/actions/setup-python/releases/tag/v5.3.0 => https://github.com/actions/setup-python/blob/0b93645e9fea7318ecaed2b359559ac225c90a2b/src/setup-python.ts (oui c’est peu compréhensible de but en blanc, mais lors de problèmes c’est pratique de pouvoir voir du code, pour comprendre #opensource)
Que souhaite-t-on automatiser ?#
La création et configuration des environnements
Exécution automatique des tests
Analyse de la qualité du code (lint)
Validation de la qualimétrie via des outils et bots
Nos préconisations
👉 Nous préconisons la mise en place systématique des tests et du lint sur vos projets, de façon transverse, en complément des githooks locaux, afin de garantir une qualité de code constante dès les premières étapes du développement.
Scripts exemples fonctionnels#
Pour une application qui utilise UV nous avons un script exemple ici :
name: CI Python avec uv
on:
push:
branches: [ '**' ]
pull_request:
branches: [ main, develop ]
jobs:
format:
name: Format check avec Ruff
runs-on: ubuntu-22.04
steps:
- name: Récupérer le code
uses: actions/checkout@v4
- name: Installer uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
- name: Configurer Python
run: uv python install
- name: Installer les dépendances
run: uv sync --dev
- name: Vérification format avec Ruff
run: uv run ruff format --check
lint:
name: Linting avec Ruff
runs-on: ubuntu-22.04
steps:
- name: Récupérer le code
uses: actions/checkout@v4
- name: Installer uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
- name: Configurer Python
run: uv python install
- name: Installer les dépendances
run: uv sync --dev
- name: Vérification lint avec Ruff
run: uv run ruff check .
test:
name: Tests avec pytest
runs-on: ubuntu-22.04
steps:
- name: Récupérer le code
uses: actions/checkout@v4
- name: Installer uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
- name: Configurer Python
run: uv python install
- name: Installer les dépendances
run: uv sync --dev
- name: Lancer les tests avec pytest
run: uv run pytestIci :
- 3 jobs : un Job
format, un JobLint, un Jobtest
Qui s’executent sur toutes les branches :
on:
push:
branches: [ '**' ]
pull_request:
branches: [ main, develop ]Les 3 jobs s’appuient sur des actions déjà construites:
actions/checkout@v4: récupère le code en l’état gitastral-sh/setup-uv@v4: installe uv dans l’environnement
Puis des scripts de test ou d’analyse via ruff
