🔝 Retour au Sommaire
GitHub Actions est un service d'intégration continue et de déploiement continu (CI/CD) intégré directement à GitHub. Il permet d'automatiser des tâches comme :
- Compiler votre code automatiquement à chaque modification
- Exécuter les tests pour vérifier que rien n'est cassé
- Vérifier la qualité du code (linting, analyse statique)
- Déployer l'application automatiquement sur les serveurs
- Générer des rapports de couverture de code
- Créer des releases et des packages
Avantages :
✅ Gratuit pour les projets open source (et généreux pour les projets privés)
✅ Intégré à GitHub : pas besoin de service externe
✅ Multi-plateforme : teste facilement sur Windows, Linux et macOS
✅ Parallélisation : teste sur plusieurs OS simultanément
✅ Automatisation complète : moins d'erreurs humaines
✅ Historique des builds : trace de toutes les compilations
Cas d'usage typiques :
- Développeur solo : vérifier que le code compile sur les deux OS
- Équipe : s'assurer qu'un commit ne casse pas le build
- Projet open source : garantir la qualité avant d'accepter une Pull Request
- Production : déployer automatiquement après validation
Un workflow GitHub Actions est défini dans un fichier YAML situé dans .github/workflows/.
Structure de base :
name: Nom du Workflow # Nom affiché dans l'interface
on: [push, pull_request] # Quand le workflow se déclenche
jobs: # Liste des tâches à exécuter
build: # Nom du job
runs-on: ubuntu-latest # Sur quel OS exécuter
steps: # Liste des étapes
- name: Première étape # Nom de l'étape
run: echo "Hello" # Commande à exécuterLes événements qui lancent le workflow :
# Déclencher sur push
on: push
# Déclencher sur plusieurs événements
on: [push, pull_request]
# Déclencher sur des branches spécifiques
on:
push:
branches:
- main
- develop
pull_request:
branches:
- mainUnités de travail qui s'exécutent (par défaut en parallèle) :
jobs:
build-windows:
runs-on: windows-latest
steps:
- name: Compilation Windows
run: fpc MonProgramme.pas
build-linux:
runs-on: ubuntu-latest
steps:
- name: Compilation Linux
run: fpc MonProgramme.pasCes deux jobs s'exécutent en parallèle sur deux machines virtuelles différentes.
Actions individuelles dans un job :
steps:
- name: Récupérer le code
uses: actions/checkout@v3
- name: Installer FreePascal
run: sudo apt install fpc
- name: Compiler
run: fpc MonProgramme.pasOS disponibles :
ubuntu-latest(Ubuntu 22.04)ubuntu-20.04(version spécifique)windows-latest(Windows Server 2022)windows-2019(version spécifique)macos-latest(macOS 12+)
jobs:
build-ubuntu:
runs-on: ubuntu-latest
steps:
- name: Checkout du code
uses: actions/checkout@v3
- name: Installer FreePascal
run: |
sudo apt-get update
sudo apt-get install -y fpc
- name: Vérifier l'installation
run: fpc -iVExplication :
sudo apt-get update: met à jour la liste des packagessudo apt-get install -y fpc: installe FreePascal (l'option-yévite la confirmation)fpc -iV: affiche la version installée
jobs:
build-windows:
runs-on: windows-latest
steps:
- name: Checkout du code
uses: actions/checkout@v3
- name: Installer FreePascal avec Chocolatey
run: choco install freepascal -y
- name: Vérifier l'installation
run: fpc -iVExplication :
choco install freepascal -y: utilise Chocolatey (gestionnaire de packages Windows)- L'option
-yaccepte automatiquement les confirmations
- name: Installer Lazarus
run: |
sudo apt-get install -y lazarus lcl- name: Installer Lazarus
run: choco install lazarus -yEmplacement : .github/workflows/build.yml
name: Build FreePascal Multi-Plateforme
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
# Job 1: Compilation sur Ubuntu
build-ubuntu:
runs-on: ubuntu-latest
steps:
- name: Récupération du code source
uses: actions/checkout@v3
- name: Installation de FreePascal
run: |
sudo apt-get update
sudo apt-get install -y fpc
- name: Affichage de la version FPC
run: fpc -iV
- name: Compilation du projet
run: |
cd src
fpc -O2 -gl MonProgramme.pas
- name: Vérification de l'exécutable
run: |
test -f src/MonProgramme
echo "✅ Compilation Ubuntu réussie"
# Job 2: Compilation sur Windows
build-windows:
runs-on: windows-latest
steps:
- name: Récupération du code source
uses: actions/checkout@v3
- name: Installation de FreePascal
run: choco install freepascal -y
- name: Affichage de la version FPC
run: fpc -iV
- name: Compilation du projet
run: |
cd src
fpc -O2 -gl MonProgramme.pas
- name: Vérification de l'exécutable
run: |
if (Test-Path src\MonProgramme.exe) {
Write-Host "✅ Compilation Windows réussie"
} else {
Write-Error "❌ Exécutable non trouvé"
exit 1
}
shell: pwshDéclencheurs :
- S'exécute sur chaque
pushvers les branchesmainoudevelop - S'exécute sur chaque
pull_requestversmain
Deux jobs en parallèle :
- build-ubuntu : compile sur Ubuntu
- build-windows : compile sur Windows
Étapes communes :
- Récupère le code avec
actions/checkout@v3 - Installe FreePascal (différemment selon l'OS)
- Affiche la version pour vérification
- Compile le projet
- Vérifie que l'exécutable existe
name: Tests FPCUnit
on: [push, pull_request]
jobs:
test-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Installation FPC et FPCUnit
run: |
sudo apt-get update
sudo apt-get install -y fpc fpcunit
- name: Compilation des tests
run: |
cd tests
fpc -Fu../src -gl TestsSuite.pas
- name: Exécution des tests
run: |
cd tests
./TestsSuite --format=plain
- name: Vérification du résultat
run: |
if [ $? -eq 0 ]; then
echo "✅ Tous les tests passent"
else
echo "❌ Des tests ont échoué"
exit 1
fi
test-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Installation FPC
run: choco install freepascal -y
- name: Compilation des tests
run: |
cd tests
fpc -Fu..\src -gl TestsSuite.pas
- name: Exécution des tests
run: |
cd tests
.\TestsSuite.exe --format=plain
- name: Vérification du résultat
shell: pwsh
run: |
if ($LASTEXITCODE -eq 0) {
Write-Host "✅ Tous les tests passent"
} else {
Write-Error "❌ Des tests ont échoué"
exit 1
}Une matrice permet de tester automatiquement plusieurs combinaisons de paramètres (OS, versions, options).
name: Matrice Multi-Versions
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
fpc-version: ['3.2.0', '3.2.2']
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Installation FPC ${{ matrix.fpc-version }} sur ${{ matrix.os }}
if: runner.os == 'Linux'
run: |
# Script d'installation selon la version
echo "Installation de FPC ${{ matrix.fpc-version }}"
sudo apt-get update
sudo apt-get install -y fpc
- name: Installation FPC ${{ matrix.fpc-version }} sur ${{ matrix.os }}
if: runner.os == 'Windows'
run: choco install freepascal -y
- name: Compilation
run: fpc -O2 MonProgramme.pasRésultat : Ce workflow crée 4 jobs automatiquement :
- Ubuntu + FPC 3.2.0
- Ubuntu + FPC 3.2.2
- Windows + FPC 3.2.0
- Windows + FPC 3.2.2
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
fpc-version: ['3.2.0', '3.2.2']
exclude:
# Exclure macOS + FPC 3.2.0 (non supporté)
- os: macos-latest
fpc-version: '3.2.0'Un artefact est un fichier généré par votre workflow (exécutable, rapport, logs) que vous pouvez télécharger ou réutiliser.
name: Build et Sauvegarde des Exécutables
on: [push]
jobs:
build-and-upload:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Installer FPC
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get update && sudo apt-get install -y fpc
elif [ "$RUNNER_OS" == "Windows" ]; then
choco install freepascal -y
fi
shell: bash
- name: Compiler
run: fpc -O2 MonProgramme.pas
- name: Upload de l'exécutable Ubuntu
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: MonProgramme-Linux
path: MonProgramme
- name: Upload de l'exécutable Windows
if: runner.os == 'Windows'
uses: actions/upload-artifact@v3
with:
name: MonProgramme-Windows
path: MonProgramme.exeRésultat : Après le build, vous pouvez télécharger MonProgramme-Linux et MonProgramme-Windows depuis l'interface GitHub Actions.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Compiler
run: fpc MonProgramme.pas
- name: Upload
uses: actions/upload-artifact@v3
with:
name: executable
path: MonProgramme
test:
needs: build # Attend que 'build' soit terminé
runs-on: ubuntu-latest
steps:
- name: Télécharger l'exécutable
uses: actions/download-artifact@v3
with:
name: executable
- name: Rendre exécutable
run: chmod +x MonProgramme
- name: Exécuter les tests
run: ./MonProgramme --run-testsname: Deploy Production
on:
push:
branches:
- main # Seulement sur la branche main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Déploiement
run: echo "Déploiement en production"steps:
- name: Étape qui s'exécute seulement sur Linux
if: runner.os == 'Linux'
run: echo "Je suis sur Linux"
- name: Étape qui s'exécute seulement sur Windows
if: runner.os == 'Windows'
run: echo "Je suis sur Windows"
- name: Étape qui s'exécute seulement sur la branche main
if: github.ref == 'refs/heads/main'
run: echo "Je suis sur main"
- name: Étape qui s'exécute seulement sur les tags
if: startsWith(github.ref, 'refs/tags/')
run: echo "C'est un tag de version"name: Validation PR
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Vérifier le code
run: |
fpc -gl -Ci src/*.pas
echo "✅ Code valide"Le cache permet de réutiliser des fichiers entre les exécutions pour gagner du temps.
name: Build avec Cache
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache des packages FPC
uses: actions/cache@v3
with:
path: |
~/.fpc
/usr/lib/fpc
key: ${{ runner.os }}-fpc-${{ hashFiles('**/fpc.cfg') }}
restore-keys: |
${{ runner.os }}-fpc-
- name: Installer FPC
run: sudo apt-get install -y fpc
- name: Compiler
run: fpc -O2 MonProgramme.pasAvantages :
- Premier build : installe FPC normalement (~2 minutes)
- Builds suivants : utilise le cache (~10 secondes)
jobs:
build:
runs-on: ubuntu-latest
env:
FPC_VERSION: 3.2.2
BUILD_CONFIG: Release
steps:
- name: Utiliser les variables
run: |
echo "Version FPC: $FPC_VERSION"
echo "Configuration: $BUILD_CONFIG"
fpc -O2 -dRELEASE MonProgramme.pasPour stocker des mots de passe, clés API, etc.
1. Ajouter un secret dans GitHub :
- Allez dans
Settings → Secrets and variables → Actions - Cliquez sur
New repository secret - Nom :
DEPLOY_TOKEN, Valeur :votre_token_secret
2. Utiliser le secret dans le workflow :
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Déployer avec token
run: |
echo "Déploiement avec token sécurisé"
curl -H "Authorization: Bearer ${{ secrets.DEPLOY_TOKEN }}" \
https://api.example.com/deployImportant : Les secrets ne sont JAMAIS affichés dans les logs !
mon-projet/
├── .github/
│ └── workflows/
│ └── ci-cd.yml
├── src/
│ └── MonProgramme.pas
├── tests/
│ └── TestsSuite.pas
└── README.md
name: Pipeline CI/CD FreePascal
on:
push:
branches: [ main, develop ]
tags:
- 'v*'
pull_request:
branches: [ main ]
env:
FPC_VERSION: 3.2.2
jobs:
# Job 1: Vérification du code
lint:
name: Analyse statique du code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Installer FPC
run: |
sudo apt-get update
sudo apt-get install -y fpc
- name: Vérifier la syntaxe
run: |
find src -name "*.pas" -exec fpc -S {} \;
# Job 2: Build multi-plateforme
build:
name: Compilation ${{ matrix.os }}
needs: lint
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
include:
- os: ubuntu-latest
executable: MonProgramme
- os: windows-latest
executable: MonProgramme.exe
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Installer FPC (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y fpc
- name: Installer FPC (Windows)
if: runner.os == 'Windows'
run: choco install freepascal -y
- name: Compiler le projet
run: |
cd src
fpc -O2 -gl -Ci MonProgramme.pas
- name: Upload de l'exécutable
uses: actions/upload-artifact@v3
with:
name: MonProgramme-${{ runner.os }}
path: src/${{ matrix.executable }}
# Job 3: Tests automatiques
test:
name: Tests ${{ matrix.os }}
needs: build
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Télécharger l'exécutable
uses: actions/download-artifact@v3
with:
name: MonProgramme-${{ runner.os }}
path: ./bin
- name: Rendre exécutable (Linux)
if: runner.os == 'Linux'
run: chmod +x bin/MonProgramme
- name: Installer FPC
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get update && sudo apt-get install -y fpc fpcunit
elif [ "$RUNNER_OS" == "Windows" ]; then
choco install freepascal -y
fi
shell: bash
- name: Compiler les tests
run: |
cd tests
fpc -Fu../src -gl TestsSuite.pas
- name: Exécuter les tests
run: |
cd tests
if [ "$RUNNER_OS" == "Linux" ]; then
./TestsSuite --format=plain
else
./TestsSuite.exe --format=plain
fi
shell: bash
# Job 4: Release automatique (seulement sur tags)
release:
name: Créer une Release
if: startsWith(github.ref, 'refs/tags/v')
needs: [build, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Télécharger tous les artefacts
uses: actions/download-artifact@v3
- name: Créer l'archive Linux
run: |
cd MonProgramme-Linux
tar -czf ../MonProgramme-Linux-${{ github.ref_name }}.tar.gz *
- name: Créer l'archive Windows
run: |
cd MonProgramme-Windows
zip -r ../MonProgramme-Windows-${{ github.ref_name }}.zip *
- name: Créer la Release GitHub
uses: softprops/action-gh-release@v1
with:
files: |
MonProgramme-Linux-${{ github.ref_name }}.tar.gz
MonProgramme-Windows-${{ github.ref_name }}.zip
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}1. Analyse statique (lint)
- Vérifie la syntaxe de tous les fichiers
.pas - S'exécute en premier pour détecter rapidement les erreurs
2. Compilation multi-plateforme (build)
- Compile sur Ubuntu et Windows en parallèle
- Sauvegarde les exécutables comme artefacts
- Utilise une matrice pour éviter la duplication
3. Tests automatiques (test)
- Télécharge les exécutables compilés
- Compile et exécute la suite de tests FPCUnit
- Valide sur les deux plateformes
4. Release automatique (release)
- S'exécute seulement quand vous créez un tag (ex:
v1.0.0) - Crée des archives
.tar.gzet.zip - Publie automatiquement une Release GitHub avec les binaires
Ajoutez un badge pour montrer l'état de votre build :
# Mon Projet FreePascal
Le badge affichera :
- ✅ Vert si le build passe
- ❌ Rouge si le build échoue
- 🟡 Jaune si le build est en cours
steps:
- name: Debug - Informations système
run: |
echo "OS: $RUNNER_OS"
echo "Architecture: $RUNNER_ARCH"
echo "Workspace: $GITHUB_WORKSPACE"
echo "Branch: $GITHUB_REF"
echo "Commit: $GITHUB_SHA"
- name: Debug - Lister les fichiers
run: |
ls -la
pwdDans GitHub :
- Allez dans
Settings → Secrets and variables → Actions - Ajoutez deux secrets :
ACTIONS_RUNNER_DEBUG=trueACTIONS_STEP_DEBUG=true
Les logs afficheront beaucoup plus de détails.
act permet d'exécuter GitHub Actions localement :
# Installation (Linux)
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# Exécuter le workflow localement
act -j build❌ Mauvais :
steps:
- name: Step 1
run: fpc test.pas✅ Bon :
steps:
- name: Compilation des tests unitaires
run: fpc -Fu../src tests/TestsSuite.passtrategy:
fail-fast: false # Continue même si un job échoue
matrix:
os: [ubuntu-latest, windows-latest]Sans fail-fast: false, si Windows échoue, Ubuntu est annulé automatiquement.
jobs:
build:
# Compile le code
test:
needs: build # Attend la fin du build
# Exécute les testsAvantage : en cas d'échec de compilation, les tests ne s'exécutent pas inutilement.
✅ Bon :
- uses: actions/checkout@v3 # Version fixe❌ Risqué :
- uses: actions/checkout@main # Peut changer sans prévenirLes artefacts consomment de l'espace de stockage :
- name: Upload de l'exécutable
uses: actions/upload-artifact@v3
with:
name: executable
path: MonProgramme
retention-days: 7 # Supprimer après 7 joursAu lieu de mettre beaucoup de lignes run:, créez un script :
scripts/build.sh :
#!/bin/bash
set -e
echo "Compilation en cours..."
cd src
fpc -O2 -gl MonProgramme.pas
echo "✅ Compilation réussie"Workflow :
steps:
- name: Compiler
run: bash scripts/build.sh| Type de Compte | Minutes Gratuites | Espace Artefacts |
|---|---|---|
| Public (open source) | Illimité | 500 MB |
| Privé (Free) | 2000 minutes | 500 MB |
| Privé (Pro) | 3000 minutes | 1 GB |
| Privé (Team) | 3000 minutes | 2 GB |
| OS | Multiplicateur |
|---|---|
| Linux | 1x |
| Windows | 2x |
| macOS | 10x |
Exemple : Un build de 10 minutes sur Windows compte comme 20 minutes.
- Utiliser le cache pour réduire les temps de build
- Privilégier Linux quand c'est possible
- Paralléliser intelligemment sans abus
- Nettoyer les artefacts régulièrement
jobs:
build:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: fpc MonProgramme.pasSi votre commit contient [skip ci], le build est ignoré.
jobs:
notify:
runs-on: ubuntu-latest
if: always() # S'exécute même si les autres jobs échouent
needs: [build, test]
steps:
- name: Notifier sur Discord
if: failure()
run: |
curl -X POST ${{ secrets.DISCORD_WEBHOOK }} \
-H "Content-Type: application/json" \
-d '{"content":"❌ Build échoué pour ${{ github.repository }}"}'
- name: Notifier sur Slack
if: success()
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
-H "Content-Type: application/json" \
-d '{
"text": "✅ Build réussi pour ${{ github.repository }}",
"attachments": [{
"color": "good",
"fields": [{
"title": "Branche",
"value": "${{ github.ref_name }}",
"short": true
}, {
"title": "Commit",
"value": "${{ github.sha }}",
"short": true
}]
}]
}'Configuration :
- Créez un webhook dans Discord/Slack
- Ajoutez-le comme secret :
DISCORD_WEBHOOKouSLACK_WEBHOOK - Le workflow envoie automatiquement des notifications
name: Déploiement Production
on:
push:
branches:
- main
tags:
- 'v*'
jobs:
deploy:
name: Déployer sur serveur Linux
runs-on: ubuntu-latest
steps:
- name: Checkout du code
uses: actions/checkout@v3
- name: Installer FreePascal
run: |
sudo apt-get update
sudo apt-get install -y fpc
- name: Compiler pour production
run: |
cd src
fpc -O3 -XXs -CX MonProgramme.pas
- name: Créer l'archive de déploiement
run: |
mkdir -p deploy
cp src/MonProgramme deploy/
cp -r config deploy/
tar -czf deploy.tar.gz deploy/
- name: Déployer via SSH
uses: appleboy/scp-action@master
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
source: "deploy.tar.gz"
target: "/tmp/"
- name: Extraire et redémarrer le service
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
cd /opt/monapp
sudo systemctl stop monapp
tar -xzf /tmp/deploy.tar.gz
cp -r deploy/* .
sudo systemctl start monapp
sudo systemctl status monapp
rm -rf /tmp/deploy.tar.gz deploy/Secrets nécessaires :
DEPLOY_HOST: IP ou nom d'hôte du serveurDEPLOY_USER: Nom d'utilisateur SSHDEPLOY_SSH_KEY: Clé privée SSH (format PEM)
jobs:
deploy-windows:
name: Déployer sur serveur Windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Compiler
run: |
choco install freepascal -y
cd src
fpc -O3 MonProgramme.pas
- name: Copier vers le serveur
run: |
# Utiliser WinSCP ou PowerShell Remoting
$secPassword = ConvertTo-SecureString "${{ secrets.DEPLOY_PASSWORD }}" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("${{ secrets.DEPLOY_USER }}", $secPassword)
$session = New-PSSession -ComputerName ${{ secrets.DEPLOY_HOST }} -Credential $credential
Copy-Item -Path "src\MonProgramme.exe" `
-Destination "C:\Apps\MonApp\" `
-ToSession $session
Invoke-Command -Session $session -ScriptBlock {
Stop-Service -Name "MonAppService"
Start-Service -Name "MonAppService"
}
Remove-PSSession $session
shell: pwshname: Docker Build et Push
on:
push:
branches: [ main ]
tags: [ 'v*' ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login vers GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Build et Push image Docker
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=maxDockerfile FreePascal :
# Dockerfile
FROM ubuntu:22.04 as builder
# Installer FreePascal
RUN apt-get update && \
apt-get install -y fpc && \
rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Copier le code source
COPY src/ ./src/
# Compiler
RUN cd src && fpc -O3 -XXs MonProgramme.pas
# Image finale légère
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y ca-certificates && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copier l'exécutable compilé
COPY --from=builder /build/src/MonProgramme .
# Copier les fichiers de configuration
COPY config/ ./config/
# Exposition du port (si applicable)
EXPOSE 8080
# Commande de démarrage
CMD ["./MonProgramme"]name: Tests de Performance
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Installer FreePascal
run: |
sudo apt-get update
sudo apt-get install -y fpc
- name: Compiler avec optimisations
run: |
cd src
fpc -O3 -Xs MonProgramme.pas
- name: Exécuter les benchmarks
run: |
./src/MonProgramme --benchmark > benchmark_results.txt
cat benchmark_results.txt
- name: Analyser les résultats
run: |
# Extraire le temps d'exécution
TIME=$(grep "Temps total:" benchmark_results.txt | awk '{print $3}')
echo "Temps d'exécution: $TIME secondes"
# Comparer avec la baseline
BASELINE=10.0
if (( $(echo "$TIME > $BASELINE" | bc -l) )); then
echo "⚠️ Performance dégradée: $TIME s (baseline: $BASELINE s)"
exit 1
else
echo "✅ Performance acceptable: $TIME s"
fi
- name: Upload des résultats
uses: actions/upload-artifact@v3
with:
name: benchmark-results
path: benchmark_results.txt
- name: Commenter la PR avec les résultats
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const results = fs.readFileSync('benchmark_results.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 📊 Résultats des Benchmarks\n\`\`\`\n${results}\n\`\`\``
});name: Analyse de Sécurité
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Scan hebdomadaire le lundi à 9h
- cron: '0 9 * * 1'
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Scanner les dépendances
run: |
# Rechercher les bibliothèques connues avec vulnérabilités
echo "Analyse des dépendances..."
find . -name "*.pas" -exec grep -l "uses.*SysUtils" {} \;
- name: Analyser le code pour les patterns dangereux
run: |
echo "Recherche de patterns de code dangereux..."
# Rechercher les commandes shell potentiellement dangereuses
if grep -r "ShellExecute\|Exec\|System(" src/; then
echo "⚠️ Commandes shell détectées - vérifier la sécurité"
fi
# Rechercher les allocations mémoire non libérées
if grep -r "GetMem\|New(" src/ | grep -v "FreeMem\|Dispose"; then
echo "⚠️ Allocations mémoire potentiellement non libérées"
fi
- name: Vérifier les permissions de fichiers
run: |
# S'assurer qu'aucun fichier exécutable n'est commité par erreur
find . -type f -perm /111 ! -name "*.sh" | grep -v ".git" || truejobs:
code-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Installer les outils d'analyse
run: |
sudo apt-get update
sudo apt-get install -y fpc cloc
- name: Statistiques du code
run: |
echo "## 📊 Statistiques du Code" > code_stats.md
echo "" >> code_stats.md
cloc src/ --md >> code_stats.md
cat code_stats.md
- name: Analyser la complexité
run: |
# Compter les fonctions longues (>100 lignes)
echo "Recherche de fonctions trop longues..."
for file in src/*.pas; do
awk '/^(function|procedure)/{start=NR} /^end;/{
if (NR-start > 100)
print FILENAME ":" start " - Fonction trop longue (" NR-start " lignes)"
}' "$file"
done
- name: Vérifier les standards de code
run: |
# Vérifier l'indentation
echo "Vérification de l'indentation..."
find src/ -name "*.pas" -exec grep -n "^[^ ]" {} + | grep -v "^[^:]*:[0-9]*:(uses\|type\|var\|const\|begin\|end)" || true
- name: Commenter la PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const stats = fs.readFileSync('code_stats.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: stats
});name: Documentation
on:
push:
branches: [ main ]
jobs:
generate-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Installer PasDoc
run: |
sudo apt-get update
sudo apt-get install -y pasdoc
- name: Générer la documentation
run: |
mkdir -p docs/api
pasdoc \
--source src/ \
--output docs/api/ \
--format html \
--title "Documentation API - Mon Projet" \
--introduction README.md
- name: Créer l'index de documentation
run: |
cat > docs/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Documentation - Mon Projet FreePascal</title>
<meta charset="UTF-8">
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
h1 { color: #333; }
.link-box {
background: #f5f5f5;
padding: 20px;
margin: 10px 0;
border-radius: 5px;
}
</style>
</head>
<body>
<h1>📚 Documentation - Mon Projet FreePascal</h1>
<div class="link-box">
<h2>🔗 Liens Utiles</h2>
<ul>
<li><a href="api/">Documentation API</a></li>
<li><a href="https://github.com/${{ github.repository }}">Code Source</a></li>
<li><a href="https://github.com/${{ github.repository }}/releases">Releases</a></li>
</ul>
</div>
</body>
</html>
EOF
- name: Déployer sur GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
publish_branch: gh-pagesConfiguration GitHub Pages :
- Allez dans
Settings → Pages - Source :
Deploy from a branch - Branch :
gh-pages/root - Votre documentation sera accessible à
https://username.github.io/repo/
name: Release Automatique
on:
push:
branches: [ main ]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Récupère tout l'historique git
- name: Analyser les commits
id: semantic
uses: paulhatch/semantic-version@v5.0.2
with:
tag_prefix: "v"
major_pattern: "(BREAKING CHANGE|MAJOR)"
minor_pattern: "(feat|FEATURE)"
patch_pattern: "(fix|bugfix|patch)"
format: "${major}.${minor}.${patch}"
- name: Générer le changelog
id: changelog
run: |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$PREVIOUS_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges)
else
COMMITS=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
fi
echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
echo "## Version ${{ steps.semantic.outputs.version }}" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "### Changements :" >> $GITHUB_OUTPUT
echo "$COMMITS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Compiler les binaires
run: |
sudo apt-get update && sudo apt-get install -y fpc
cd src
fpc -O3 MonProgramme.pas
- name: Créer le tag
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git tag -a "v${{ steps.semantic.outputs.version }}" -m "Release v${{ steps.semantic.outputs.version }}"
git push origin "v${{ steps.semantic.outputs.version }}"
- name: Créer la Release GitHub
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.semantic.outputs.version }}
name: Release v${{ steps.semantic.outputs.version }}
body: ${{ steps.changelog.outputs.CHANGELOG }}
draft: false
prerelease: false
files: |
src/MonProgramme
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Convention de commits pour semantic versioning :
feat: Nouvelle fonctionnalité → Version mineure (1.0.0 → 1.1.0)
fix: Correction de bug → Version patch (1.0.0 → 1.0.1)
BREAKING CHANGE: Changement majeur → Version majeure (1.0.0 → 2.0.0)
Fichier .github/workflows/build-reusable.yml :
name: Build Réutilisable
on:
workflow_call:
inputs:
os:
required: true
type: string
fpc-version:
required: false
type: string
default: 'latest'
build-config:
required: false
type: string
default: 'Release'
outputs:
artifact-name:
description: "Nom de l'artefact créé"
value: ${{ jobs.build.outputs.artifact }}
jobs:
build:
runs-on: ${{ inputs.os }}
outputs:
artifact: ${{ steps.upload.outputs.artifact-name }}
steps:
- uses: actions/checkout@v3
- name: Installer FPC (${{ inputs.os }})
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get update && sudo apt-get install -y fpc
elif [ "$RUNNER_OS" == "Windows" ]; then
choco install freepascal -y
fi
shell: bash
- name: Compiler (${{ inputs.build-config }})
run: |
cd src
if [ "${{ inputs.build-config }}" == "Release" ]; then
fpc -O3 -XXs MonProgramme.pas
else
fpc -g -gl MonProgramme.pas
fi
shell: bash
- name: Upload artefact
id: upload
uses: actions/upload-artifact@v3
with:
name: MonProgramme-${{ runner.os }}-${{ inputs.build-config }}
path: src/MonProgramme*Fichier .github/workflows/main.yml :
name: Pipeline Principal
on: [push, pull_request]
jobs:
build-linux-debug:
uses: ./.github/workflows/build-reusable.yml
with:
os: ubuntu-latest
build-config: Debug
build-linux-release:
uses: ./.github/workflows/build-reusable.yml
with:
os: ubuntu-latest
build-config: Release
build-windows-release:
uses: ./.github/workflows/build-reusable.yml
with:
os: windows-latest
build-config: ReleaseAvantages :
- ✅ Évite la duplication de code
- ✅ Maintenance centralisée
- ✅ Réutilisable dans plusieurs workflows
name: Tests Paramétrés
on: [push, pull_request]
jobs:
prepare-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v3
- name: Générer la matrice de test
id: set-matrix
run: |
# Lire les configurations depuis un fichier JSON
MATRIX=$(cat .github/test-matrix.json | jq -c .)
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
test:
needs: prepare-matrix
strategy:
matrix: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Test ${{ matrix.test-name }}
run: |
echo "Exécution du test: ${{ matrix.test-name }}"
echo "Paramètres: ${{ matrix.params }}"Fichier .github/test-matrix.json :
{
"include": [
{
"os": "ubuntu-latest",
"test-name": "Performance Tests",
"params": "--benchmark"
},
{
"os": "ubuntu-latest",
"test-name": "Integration Tests",
"params": "--integration"
},
{
"os": "windows-latest",
"test-name": "UI Tests",
"params": "--ui-tests"
}
]
}jobs:
build-with-retry:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Compiler avec retry
uses: nick-invision/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 30
command: |
sudo apt-get update
sudo apt-get install -y fpc
cd src
fpc -O2 MonProgramme.pas
- name: Tests avec retry
uses: nick-invision/retry@v2
with:
timeout_minutes: 5
max_attempts: 2
command: |
./tests/run_tests.shjobs:
mandatory-build:
runs-on: ubuntu-latest
steps:
- name: Build principal
run: fpc MonProgramme.pas
optional-benchmark:
runs-on: ubuntu-latest
continue-on-error: true # N'arrête pas le workflow si ce job échoue
steps:
- name: Benchmark
run: ./benchmark.sh
deployment:
needs: mandatory-build # N'attend PAS optional-benchmark
runs-on: ubuntu-latest
steps:
- name: Déployer
run: ./deploy.shFichier .github/actions/setup-fpc/action.yml :
name: 'Setup FreePascal'
description: 'Installe FreePascal avec cache'
inputs:
version:
description: 'Version de FPC à installer'
required: false
default: 'latest'
cache:
description: 'Activer le cache'
required: false
default: 'true'
outputs:
fpc-version:
description: 'Version de FPC installée'
value: ${{ steps.get-version.outputs.version }}
runs:
using: 'composite'
steps:
- name: Cache FPC
if: inputs.cache == 'true'
uses: actions/cache@v3
with:
path: |
~/.fpc
/usr/lib/fpc
key: ${{ runner.os }}-fpc-${{ inputs.version }}
- name: Installer FPC (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y fpc
shell: bash
- name: Installer FPC (Windows)
if: runner.os == 'Windows'
run: choco install freepascal -y
shell: pwsh
- name: Obtenir la version
id: get-version
run: echo "version=$(fpc -iV)" >> $GITHUB_OUTPUT
shell: bashjobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup FreePascal
uses: ./.github/actions/setup-fpc
with:
version: 'latest'
cache: 'true'
- name: Compiler
run: fpc MonProgramme.pas✅ Organisation
- Noms de workflows explicites
- Jobs bien séparés (build/test/deploy)
- Commentaires dans les fichiers YAML complexes
✅ Performance
- Cache activé pour les dépendances
- Parallélisation des jobs indépendants
- Artefacts nettoyés automatiquement
✅ Sécurité
- Secrets utilisés pour les données sensibles
- Pas de secrets dans les logs
- Permissions minimales pour les tokens
✅ Qualité
- Tests automatiques à chaque commit
- Couverture de code mesurée
- Déploiement uniquement après validation
✅ Maintenance
- Versions fixées pour les actions (
@v3au lieu de@main) - Documentation du workflow
- Notifications configurées
Documentation officielle :
Actions populaires pour FreePascal :
actions/checkout@v3- Récupérer le codeactions/upload-artifact@v3- Sauvegarder les artefactsactions/cache@v3- Mise en cachesoftprops/action-gh-release@v1- Créer des releases
Pour un projet FreePascal professionnel, voici une structure recommandée :
.github/
├── workflows/
│ ├── ci.yml # Build et tests continus
│ ├── release.yml # Création de releases
│ ├── documentation.yml # Génération de docs
│ └── security.yml # Scans de sécurité
├── actions/
│ └── setup-fpc/ # Action composite réutilisable
│ └── action.yml
└── test-matrix.json # Configuration des tests
src/
tests/
docs/
scripts/
Avec GitHub Actions, vous automatisez complètement votre workflow de développement FreePascal, du commit au déploiement, sur Windows et Ubuntu en parallèle ! 🚀