Le Contexte
Le projet ClientApp est une application full-stack composée de deux repositories GitHub distincts :
- Frontend : une SPA React 19 avec TypeScript, Vite, Material Tailwind
- Backend : une API Laravel 11 avec Sanctum, Spatie Permissions, Docker
L'application est déployée sur un VPS avec Docker pour le backend et Nginx pour le frontend. Le client demande à recevoir le code source de l'application. Le défi : partager un code propre, sans fichiers inutiles ni traces de l'outillage de développement, tout en préservant l'intégrité du projet en cours de développement.
Le Problème
Dans un projet réel, le code local accumule beaucoup de fichiers qui n'ont rien à faire dans une livraison :
| Type de fichier | Exemples | Pourquoi les exclure |
|---|---|---|
| Configuration IA | .env/, fichiers .md de contexte | Outillage interne du développeur |
| Fichiers backup | Login_v0.tsx, UserForm_ok.tsx | Anciennes versions gardées "au cas où" |
| Scripts de dev | fix-db.sh, scripts de déploiement | Spécifiques à l'environnement du dev |
| Artefacts système | nul (artefact Windows) | Fichiers parasites |
| Dépendances | node_modules/, vendor/ | Réinstallables via npm/composer |
| Secrets | .env, credentials | Sécurité |
Question supplémentaire : le code local est-il vraiment la version la plus fiable ? Ou vaut-il mieux récupérer le code directement depuis le serveur de production ?
L'Approche Retenue : Branches Git Dédiées
Plutôt que de créer une archive ZIP ou de partager le repo entier, la solution choisie est de créer une branche demo dédiée sur chaque repository GitHub. Avantages :
- Le client accède au code via GitHub (interface familière)
- La branche de travail (
stable-feature) reste intacte - On contrôle exactement ce qui est visible
- Le client peut cloner directement avec
git clone -b demo
Étape 1 : Audit des Fichiers Inutiles
Avant de créer les branches, un audit complet a été mené sur les deux projets pour identifier tous les fichiers à exclure.
Frontend - Résultat de l'audit
Fichiers à exclure :
- src/pages/auth/Login_v0.tsx (backup ancien login)
- src/pages/users/UserForm_v0.tsx (backup ancien formulaire)
- src/pages/users/UserForm_ok.tsx (backup intermédiaire)
Verdict : Le frontend était propre. Ces 3 fichiers étaient non-traqués par git (jamais commités), donc ils n'apparaîtront pas dans la branche demo.
Backend - Résultat de l'audit
Fichiers à exclure :
- fix-db.sh (script de réparation DB)
- nul (artefact Windows)
- docs-internes/ (documents de référence internes)
- *.sh (tous les scripts shell)
Problème supplémentaire : Le backend avait 28 fichiers modifiés non-commités et 21 nouveaux fichiers non-traqués. Tout le travail récent (middlewares, nouveaux modules, comptes de test, ActionLogger) n'était que local.
Étape 2 : Branche Demo Frontend (Simple)
Le frontend étant propre et à jour sur stable-feature, la création de la branche demo était directe :
cd frontend-monprojet
git checkout -b demo # Créer la branche depuis stable-feature
git push -u origin demo # Pousser sur GitHub
git checkout stable-feature # Revenir à la branche de travail
Temps : ~30 secondes. Aucune modification nécessaire.
Étape 3 : Branche Demo Backend (Complexe)
Le backend a nécessité plusieurs approches avant d'arriver à la solution finale.
Approche 1 : Commit local direct (première tentative)
L'idée initiale était de :
- Créer la branche
demodepuisstable-feature - Mettre à jour le
.gitignorepour exclure les fichiers inutiles - Stager manuellement chaque fichier applicatif
- Commiter et pousser
# Ajout au .gitignore
*.sh
nul
docs-internes/
Le staging a été fait fichier par fichier pour ne pas inclure les fichiers inutiles :
git add src/app/Http/Controllers/Api/*.php
git add src/app/Http/Middleware/
git add src/app/Models/*.php
git add src/app/Services/ActionLogger.php
# ... etc
Résultat : Branche poussée avec succès, mais une réflexion a émergé : le code local est-il vraiment identique à ce qui tourne en production ?
Approche 2 : Récupération depuis le VPS (approche retenue)
La décision a été prise de récupérer le code directement depuis le serveur de production pour garantir que la branche demo reflète exactement ce que le client verra en fonctionnement.
Tentative 2a : SCP récursif (échec)
Première approche : télécharger le dossier app/ directement avec scp -r.
scp -r -P 22 deployer@mon-vps:/var/www/monprojet/src/app local_dir/
Problème : Le téléchargement était extrêmement lent (plus de 4 minutes d'attente sans fin visible). Le dossier contenait potentiellement des milliers de fichiers si des caches ou logs étaient inclus.
Tentative 2b : Archive tar compressée (succès)
Solution beaucoup plus efficace : créer une archive compressée sur le serveur en excluant les fichiers lourds, puis télécharger un seul fichier.
# Sur le VPS via SSH
ssh deployer@mon-vps "cd /var/www/monprojet/src && tar czf /home/deployer/backend_demo.tar.gz \
--exclude='vendor' \
--exclude='node_modules' \
--exclude='storage/logs' \
--exclude='storage/framework/cache' \
--exclude='storage/framework/sessions' \
--exclude='storage/framework/views' \
--exclude='.env' ."
# Téléchargement (un seul fichier de 742 Ko au lieu de milliers)
scp -P 22 deployer@mon-vps:/home/deployer/backend_demo.tar.gz ./
Résultat : 742 Ko téléchargés en quelques secondes au lieu de minutes.
Tentative 2c : Extraction sous Windows (ajustements)
L'extraction de l'archive a rencontré deux problèmes spécifiques à l'environnement Windows :
1. Chemins Windows vs Unix : tar dans Git Bash n'interprète pas correctement les chemins D:\.... Solution : utiliser les chemins Unix-style /d/...
# Échec
tar xzf "D:\dossier\backend_demo.tar.gz" -C "D:\dossier\vps_extract"
# Succès
tar xzf "/d/dossier/backend_demo.tar.gz" -C /d/tmp_vps
2. Symlinks Linux : L'archive contenait un lien symbolique (public/storage -> /var/www/html/storage/app/public) qui ne peut pas être créé sous Windows. Solution : exclure ce symlink à l'extraction.
tar xzf archive.tar.gz -C /d/tmp_vps --exclude='./public/storage'
Intégration finale
Une fois le code extrait, le processus d'intégration dans la branche demo :
# 1. Nettoyer l'index git (supprimer les anciens fichiers traqués)
git rm -r --cached src/app src/bootstrap src/config ...
# 2. Supprimer physiquement les anciens fichiers
rm -rf src/app src/bootstrap ...
# 3. Copier le code du VPS
cp -r /d/tmp_vps/app /d/tmp_vps/bootstrap ... src/
# 4. Stager, commiter, pousser
git add .gitignore src/
git commit -m "Version demo - code production VPS"
git push origin demo
Étape 4 : Nettoyage
Après la création des branches, nettoyage complet :
# Local
rm -rf /d/tmp_vps backend_demo.tar.gz vps_backend_tmp vps_extract
# Sur le VPS
ssh deployer@mon-vps "rm -f /home/deployer/backend_demo.tar.gz"
# Retour aux branches de travail
git checkout stable-feature # sur les deux projets
Résumé des Approches
| # | Approche | Résultat | Raison |
|---|---|---|---|
| 1 | Commit local direct | Fonctionnel mais pas idéal | Code local peut différer de la production |
| 2a | SCP récursif du VPS | Abandonné | Trop lent (milliers de fichiers) |
| 2b | Archive tar + SCP | Retenue | Rapide (742 Ko), fiable, code de production |
| 2c | Extraction Windows | Ajustée | Chemins Unix + exclusion symlinks |
Résultat Final
| Projet | Branche | Contenu |
|---|---|---|
| Frontend | demo | Code React complet, propre |
| Backend | demo | Code Laravel de production, sans vendor/node_modules/.env |
Ce qui est inclus
- Tout le code applicatif (controllers, models, migrations, routes, views, config)
- Les fichiers de configuration (composer.json, package.json, vite.config.js, etc.)
- Les tests unitaires et fonctionnels
Ce qui est exclu
- Fichiers de configuration et de contexte internes
- Scripts shell (
*.sh) - Fichiers système parasites (
nul) - Documents de référence internes
- Dépendances (
vendor/,node_modules/) - réinstallables - Variables d'environnement (
.env) - sécurité - Fichiers backup (
*_v0.*,*_ok.*)
Leçons Apprises
1. Toujours privilégier le code de production pour une livraison client. Le code local peut contenir des modifications non testées.
2.tar>scp -rpour transférer du code depuis un serveur. Compresser avant de transférer réduit drastiquement le temps (742 Ko vs potentiellement des dizaines de Mo).
3. Les branches Git sont idéales pour la livraison : elles isolent le code livré du code de développement sans dupliquer le repository.
4. Windows + tar + chemins avec espaces = problèmes garantis. Toujours utiliser les chemins Unix-style dans Git Bash.
5. Les symlinks Linux ne fonctionnent pas sous Windows. Toujours les exclure lors de l'extraction d'archives provenant de serveurs Linux.
6. Mettre à jour le .gitignore AVANT de stager pour éviter d'inclure accidentellement des fichiers inutiles.
Conclusion
Livrer du code propre à un client ne se résume pas à envoyer un ZIP. C'est un processus qui demande de la rigueur : auditer les fichiers, choisir la bonne source (production vs local), et utiliser les bons outils (branches Git, tar, .gitignore). En prenant le temps de créer des branches demo dédiées, on offre au client une vue professionnelle du code tout en préservant notre environnement de développement. Cette approche est réutilisable sur n'importe quel projet full-stack et s'adapte à tous les workflows Git.