WordPress Hooks : Actions et Filtres expliqués avec exemples
Introduction Le système de hooks (crochets) de WordPress est l'épine dorsale de son architecture extensible.…
Le choix du bon workflow Git est crucial pour la productivité de l’équipe et la qualité du code. Ce guide compare les trois workflows les plus populaires avec des exemples concrets et des recommendations basées sur le contexte de votre projet.
GitFlow définit une structure de branches stricte autour des releases du projet.
master (production)
|
+-- develop (intégration)
|
+-- feature/ (nouvelles fonctionnalités)
+-- release/ (préparation release)
+-- hotfix/ (corrections urgentes)
# Installation de git-flow
# Ubuntu/Debian
sudo apt-get install git-flow
# macOS
brew install git-flow
# Windows
# Télécharger depuis https://github.com/nvie/gitflow/wiki/Windows
# Initialisation dans un projet
cd mon-projet
git flow init
# Configuration recommandée
# Branch name for production releases: master
# Branch name for "next release" development: develop
# Feature branches prefix: feature/
# Bugfix branches prefix: bugfix/
# Release branches prefix: release/
# Hotfix branches prefix: hotfix/
# Support branches prefix: support/
# Version tag prefix: v
# Créer une nouvelle feature
git flow feature start user-authentication
# Développement...
git add .
git commit -m "feat: add login form"
git commit -m "feat: implement JWT authentication"
git commit -m "test: add auth unit tests"
# Terminer la feature (merge dans develop)
git flow feature finish user-authentication
# Publier une feature pour collaboration
git flow feature publish user-authentication
# Récupérer une feature publiée
git flow feature pull origin user-authentication
# Créer une branche de release depuis develop
git flow release start 1.2.0
# Corrections mineures et préparation
echo "1.2.0" > VERSION
git add VERSION
git commit -m "chore: bump version to 1.2.0"
# Mettre à jour CHANGELOG
cat >> CHANGELOG.md << EOF
## [1.2.0] - $(date +%Y-%m-%d)
### Added
- User authentication with JWT
- Password reset functionality
- Two-factor authentication
### Fixed
- Session timeout issues
- Memory leak in auth module
EOF
git add CHANGELOG.md
git commit -m "docs: update changelog for v1.2.0"
# Terminer la release (merge dans master et develop)
git flow release finish 1.2.0
# Pousser les modifications et les tags
git checkout master
git push origin master
git checkout develop
git push origin develop
git push origin --tags
# Créer un hotfix depuis master
git flow hotfix start 1.2.1
# Correction critique
git add .
git commit -m "fix: critical security vulnerability in auth"
# Tests
npm run test
npm run test:integration
# Terminer le hotfix
git flow hotfix finish 1.2.1
# Déployer immédiatement
git push origin master
git push origin develop
git push origin --tags
Créez .git/hooks/pre-commit :
#!/bin/bash
# Vérifier la branche courante
BRANCH=$(git symbolic-ref --short HEAD)
# Interdire les commits directs sur master/develop
if [[ "$BRANCH" == "master" ]] || [[ "$BRANCH" == "develop" ]]; then
echo "ERROR: Commits directs interdits sur $BRANCH"
echo "Utilisez git flow pour créer une feature/hotfix/release"
exit 1
fi
# Vérifier le format du message de commit
COMMITMSGFILE=$1
COMMITMSG=$(cat "$COMMITMSGFILE")
# Pattern conventional commits
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf)((.+))?: .{1,50}"
if ! echo "$COMMITMSG" | grep -qE "$PATTERN"; then
echo "ERROR: Format de commit invalide"
echo "Utilisez: type(scope): description"
echo "Types: feat, fix, docs, style, refactor, test, chore, perf"
exit 1
fi
# Lancer les tests sur les features
if [[ "$BRANCH" == feature/ ]]; then
echo "Running tests..."
npm test || exit 1
fi
exit 0
Rendez-le exécutable :
chmod +x .git/hooks/pre-commit
[gitflow "branch"]
master = main
develop = develop
[gitflow "prefix"]
feature = feature/
bugfix = bugfix/
release = release/
hotfix = hotfix/
support = support/
versiontag = v
[alias]
# Raccourcis GitFlow
fs = flow feature start
ff = flow feature finish
fp = flow feature publish
rs = flow release start
rf = flow release finish
hs = flow hotfix start
hf = flow hotfix finish
GitHub Flow est un workflow léger et orienté déploiement continu.
main (production)
|
+-- feature-1
+-- feature-2
+-- bugfix-1
Règles d’or :
main est toujours déployable# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
pullrequest:
branches: [main]
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Test
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: npm run build
- name: Archive artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: dist
- name: Deploy to production
run: |
# Déploiement vers votre infrastructure
echo "Deploying to production..."
Configuration via GitHub Settings ou API :
# Via GitHub CLI
gh api repos/:owner/:repo/branches/main/protection -X PUT --input - << EOF
{
"requiredstatuschecks": {
"strict": true,
"contexts": ["test", "build"]
},
"enforceadmins": true,
"requiredpullrequestreviews": {
"dismissalrestrictions": {},
"dismissstalereviews": true,
"requirecodeownerreviews": true,
"requiredapprovingreviewcount": 2
},
"restrictions": null,
"requiredlinearhistory": true,
"allowforcepushes": false,
"allowdeletions": false
}
EOF
# 1. Synchroniser avec main
git checkout main
git pull origin main
# 2. Créer une branche descriptive
git checkout -b add-user-profile-page
# 3. Développement itératif
git add components/UserProfile.jsx
git commit -m "feat: add user profile component"
git add api/profile.js
git commit -m "feat: add profile API endpoint"
git add tests/profile.test.js
git commit -m "test: add profile component tests"
# 4. Pousser régulièrement
git push -u origin add-user-profile-page
# 5. Ouvrir une Pull Request (tôt!)
gh pr create
--title "Add user profile page"
--body "## Changes
Add UserProfile component
Add profile API endpoint
Add comprehensive tests
## Screenshots
!Profile page
## Checklist
[x] Tests pass
[x] Documentation updated
[ ] Reviewed by @teammate"
--label "feature"
--assignee "@me"
# 6. Adresser les commentaires de review
git add .
git commit -m "refactor: extract profile form to separate component"
git push
# 7. Merger après approbation
gh pr merge --squash --delete-branch
# 8. Vérifier le déploiement
gh run watch
Créez .github/pullrequesttemplate.md :
## Description
## Type de changement
[ ] Bug fix (non-breaking change)
[ ] New feature (non-breaking change)
[ ] Breaking change
[ ] Documentation update
## Changements détaillés
## Tests
[ ] Unit tests pass
[ ] Integration tests pass
[ ] Manual testing completed
## Screenshots (si applicable)
## Checklist
[ ] Code follows style guidelines
[ ] Self-review completed
[ ] Comments added for complex code
[ ] Documentation updated
[ ] No new warnings generated
[ ] Tests added/updated
[ ] Dependent changes merged
## Related Issues
Closes #
Développement sur une branche principale avec des branches de courte durée.
trunk/main (production)
|
+-- short-lived-branch-1 (< 2 jours)
+-- short-lived-branch-2 (< 2 jours)
Principes clés :
npm install unleash-client dotenv
// config/featureFlags.js
const { initialize } = require('unleash-client');
const unleash = initialize({
url: process.env.UNLEASHURL || 'http://localhost:4242/api',
appName: 'my-app',
instanceId: process.env.INSTANCEID || 'local',
refreshInterval: 5000,
metricsInterval: 30000,
customHeaders: {
Authorization: process.env.UNLEASHAPITOKEN
}
});
unleash.on('ready', () => {
console.log('Feature flags ready');
});
unleash.on('error', (err) => {
console.error('Feature flags error:', err);
});
module.exports = unleash;
// app.js
const unleash = require('./config/featureFlags');
// Feature complète mais pas prête pour production
if (unleash.isEnabled('new-user-profile')) {
app.use('/profile', require('./routes/newProfile'));
} else {
app.use('/profile', require('./routes/oldProfile'));
}
// Feature en test A/B
app.get('/dashboard', (req, res) => {
const context = {
userId: req.user.id,
sessionId: req.sessionID,
properties: {
userSegment: req.user.segment
}
};
if (unleash.isEnabled('dashboard-v2', context)) {
res.render('dashboard-v2', { user: req.user });
} else {
res.render('dashboard-v1', { user: req.user });
}
});
// Feature progressive rollout
const showNewFeature = unleash.isEnabled('gradual-rollout', {
userId: req.user.id,
properties: {
rolloutPercentage: 25 // 25% des utilisateurs
}
});
# 1. Toujours partir de trunk à jour
git checkout main
git pull --rebase origin main
# 2. Branche de courte durée
git checkout -b add-payment-validation
# 3. Développement rapide avec feature flag
cat > src/features/payment.js << 'EOF'
const unleash = require('../config/featureFlags');
function processPayment(order) {
// Nouvelle validation derrière feature flag
if (unleash.isEnabled('strict-payment-validation')) {
return validatePaymentStrict(order);
}
// Ancienne méthode (fallback)
return validatePaymentLegacy(order);
}
function validatePaymentStrict(order) {
// Nouveau code en développement
// Activé seulement en staging/dev
return {
valid: true,
method: 'strict'
};
}
function validatePaymentLegacy(order) {
// Code de production actuel
return {
valid: true,
method: 'legacy'
};
}
module.exports = { processPayment };
EOF
# 4. Tests avec les deux chemins
cat > tests/payment.test.js << 'EOF'
describe('Payment Processing', () => {
it('should use strict validation when flag enabled', () => {
unleash.mockFeature('strict-payment-validation', true);
const result = processPayment(mockOrder);
expect(result.method).toBe('strict');
});
it('should use legacy validation when flag disabled', () => {
unleash.mockFeature('strict-payment-validation', false);
const result = processPayment(mockOrder);
expect(result.method).toBe('legacy');
});
});
EOF
# 5. Commit et push rapide
git add .
git commit -m "feat: add strict payment validation behind feature flag"
git push -u origin add-payment-validation
# 6. PR rapide (même jour)
gh pr create
--title "Add strict payment validation (behind feature flag)"
--body "Feature flag: strict-payment-validation (OFF by default)
Tests included for both paths"
--label "trunk-based"
# 7. Merge rapide après CI
gh pr merge --squash --auto
# 8. Nettoyer
git checkout main
git pull
git branch -d add-payment-validation
# .github/workflows/trunk-ci.yml
name: Trunk-Based CI
on:
push:
branches: [main]
pullrequest:
branches: [main]
jobs:
fast-feedback:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- name: Setup
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install
run: npm ci
# Tests rapides d'abord
- name: Fast unit tests
run: npm run test:unit -- --maxWorkers=4
timeout-minutes: 3
- name: Lint
run: npm run lint
timeout-minutes: 2
comprehensive-tests:
needs: fast-feedback
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v3
- name: Integration tests
run: npm run test:integration
- name: E2E tests
run: npm run test:e2e
- name: Security scan
run: npm audit --audit-level=moderate
deploy-staging:
needs: comprehensive-tests
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy to staging
run: ./scripts/deploy-staging.sh
- name: Smoke tests
run: ./scripts/smoke-tests.sh staging
- name: Notify team
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'Deployed to staging'
webhookurl: ${{ secrets.SLACKWEBHOOK }}
deploy-production:
needs: deploy-staging
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment:
name: production
url: https://app.example.com
steps:
- name: Deploy to production
run: ./scripts/deploy-production.sh
- name: Health check
run: ./scripts/health-check.sh production
| Critère | GitFlow | GitHub Flow | Trunk-Based |
|---|---|---|---|
| Complexité | Haute | Faible | Moyenne |
| Releases | Planifiées | Continues | Continues |
| Taille équipe | Grande (10+) | Petite/Moyenne | Toutes tailles |
| Cycle release | Semaines/Mois | Jours | Heures |
| Maturité CI/CD | Moyenne | Haute | Très haute |
| Feature flags | Optionnel | Optionnel | Obligatoire |
| Code review | Avant merge | Obligatoire | Rapide |
| Hotfixes | Branche dédiée | Branche normale | Commit direct |
| Courbe apprentissage | Raide | Douce | Moyenne |
context:
- Releases planifiées (tous les 2-3 mois)
- Plusieurs versions en maintenance
- Équipe grande et distribuée
- Produit packagé (desktop, mobile app)
- Process de validation long
exemples:
- Applications enterprise
- Produits desktop
- Applications mobiles natives
- Firmware/embedded systems
context:
- Déploiement continu (plusieurs fois/jour)
- Une seule version en production
- Équipe petite/moyenne (< 20)
- Application web/SaaS
- CI/CD mature
exemples:
- Applications web modernes
- APIs RESTful
- Microservices
- Projets open-source
context:
- Déploiement très fréquent (> 10/jour)
- Culture DevOps mature
- Tests automatisés robustes
- Feature flags en place
- Équipe senior
exemples:
- Startups agiles
- Équipes Google/Facebook
- Microservices cloud-native
- SaaS haute vélocité
# Format
type(scope): subject
body (optionnel)
footer (optionnel)
# Types
feat: nouvelle fonctionnalité
fix: correction de bug
docs: documentation
style: formatage (pas de changement de code)
refactor: refactorisation
test: ajout de tests
chore: tâches de maintenance
# Exemples
feat(auth): add OAuth2 authentication
Implement OAuth2 with Google and GitHub providers.
Includes token refresh mechanism.
Closes #123
fix(api): prevent race condition in user creation
The user creation endpoint had a race condition when
multiple requests arrived simultaneously.
Added database constraint and request queuing.
Fixes #456
docs(readme): update deployment instructions
chore(deps): upgrade React to v18.2
test(payment): add integration tests for Stripe
# .gitconfig
[alias]
# Status court
s = status -sb
# Log formaté
l = log --oneline --graph --decorate --all
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
# Commandes rapides
co = checkout
br = branch
ci = commit
st = status
# Commit avec message
cm = commit -m
cam = commit -am
# Amend dernier commit
amend = commit --amend --no-edit
# Undo dernier commit (garde les changements)
undo = reset HEAD~1 --soft
# Clean branches merged
cleanup = !git branch --merged | grep -v '|main|develop' | xargs -n 1 git branch -d
# Show files in commit
show-files = diff-tree --no-commit-id --name-only -r
# Stash avec message
stash-save = stash save
# Pull avec rebase
up = pull --rebase --autostash
# Push force avec safety
pushf = push --force-with-lease
# Installation de pre-commit framework
pip install pre-commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: check-added-large-files
args: ['--maxkb=1000']
- id: check-merge-conflict
- id: detect-private-key
- id: no-commit-to-branch
args: ['--branch', 'main', '--branch', 'develop']
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.44.0
hooks:
- id: eslint
files: .(js|jsx|ts|tsx)$
args: ['--fix']
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
languageversion: python3.11
- repo: local
hooks:
- id: tests
name: Run tests
entry: npm test
language: system
passfilenames: false
stages: [commit]
# Installation
pre-commit install
pre-commit install --hook-type commit-msg
# Test manuel
pre-commit run --all-files
# Solution 1: Rebase régulier sur main/develop
git checkout feature-branch
git fetch origin
git rebase origin/main
# En cas de conflit
git status
# Résoudre les conflits dans les fichiers
git add .
git rebase --continue
# Solution 2: Merge main dans votre branche quotidiennement
git checkout feature-branch
git merge origin/main
# Solution 3: Branches plus courtes (< 2 jours)
# Diviser en plusieurs PRs
git checkout long-feature-branch
# Créer une branche pour la partie 1
git checkout -b feature-part-1
git reset --hard commit-hash-part-1
git push -u origin feature-part-1
# PR pour partie 1, puis partie 2, etc.
# Si pas encore pushé
git reset HEAD~1 --soft
git stash
git checkout -b correct-branch
git stash pop
git add .
git commit -m "fix: correct branch"
# Si déjà pushé (avec caution!)
git revert HEAD
git push
# Puis créer la bonne branche
# Script pour tracker les vieux feature flags
cat > scripts/check-old-flags.js << 'EOF'
const fs = require('fs');
const path = require('path');
const FLAGSCONFIG = require('./config/flags.json');
const NOW = new Date();
const WARNDAYS = 90;
FLAGSCONFIG.forEach(flag => {
const createdDate = new Date(flag.created);
const ageInDays = (NOW - createdDate) / (1000 60 60 24);
if (ageInDays > WARNDAYS && flag.enabled === true) {
console.warn(WARNING: Flag "${flag.name}" is ${Math.floor(ageInDays)} days old);
console.warn( Consider removing it and cleaning up code paths);
}
});
EOF
# Ajouter au CI
npm run check-old-flags
# 1. Merger toutes les features en cours dans develop
git checkout develop
git merge feature/branch-1
git merge feature/branch-2
# 2. Merger develop dans main
git checkout main
git merge develop
# 3. Supprimer develop
git branch -d develop
git push origin --delete develop
# 4. Mettre à jour les protections de branche
gh api repos/:owner/:repo/branches/main/protection -X PUT --input protection.json
# 5. Communiquer le changement à l'équipe
# 6. Mettre à jour CI/CD
# 1. Implémenter feature flags
npm install unleash-client
# 2. Configurer serveur Unleash
docker run -d -p 4242:4242 unleashorg/unleash-server
# 3. Migrer features progressivement derrière flags
# 4. Réduire durée des branches (objectif < 2 jours)
# 5. Augmenter fréquence des deploys
# 6. Former l'équipe aux nouvelles pratiques
# Script de métriques Git
cat > scripts/git-metrics.sh << 'EOF'
#!/bin/bash
echo "=== Git Metrics ==="
echo ""
# Nombre de commits par jour (7 derniers jours)
echo "Commits per day (last 7 days):"
git log --since="7 days ago" --pretty=format:"%ad" --date=short | sort | uniq -c
# Durée moyenne des branches
echo -e "nAverage branch lifetime:"
git for-each-ref --format='%(refname:short) %(creatordate:relative)' refs/heads/ | grep -v main
# PRs ouvertes depuis > 3 jours
echo -e "nOld open PRs (>3 days):"
gh pr list --state open --json number,title,createdAt --jq '.[] | select((.createdAt | fromdateiso8601) < (now - 259200)) | "(.number): (.title)"'
# Taille moyenne des PRs
echo -e "nAverage PR size (last 10):"
gh pr list --state closed --limit 10 --json additions,deletions --jq 'map(.additions + .deletions) | add / length'
# Temps moyen de review
echo -e "nAverage review time (last 10 merged PRs):"
gh pr list --state merged --limit 10 --json createdAt,mergedAt --jq 'map((.mergedAt | fromdateiso8601) - (.createdAt | fromdateiso8601)) | add / length / 3600 | "(.)h"'
EOF
chmod +x scripts/git-metrics.sh
./scripts/git-metrics.sh
Le choix du workflow Git dépend de votre contexte :
Recommendations finales :
Le meilleur workflow est celui que votre équipe peut suivre de manière consistante.
Cet article est vivant — corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisissez celui qui vous convient.