diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..e055a7a --- /dev/null +++ b/.gitea/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ + + +## Description + + +## Ticket lié + + +## Type de changement +- [ ] 🐞 Correction de bug +- [ ] ✨ Nouvelle fonctionnalité +- [ ] ♻️ Refactoring / dette technique +- [ ] 🔒 Sécurité +- [ ] 📄 Documentation + +## Checklist avant fusion +- [ ] Le code respecte le style du projet (`./vendor/bin/pint`) +- [ ] Les tests automatisés passent (`php artisan test`) +- [ ] Aucune dépendance vulnérable introduite (`composer audit`) +- [ ] La documentation a été mise à jour si nécessaire +- [ ] Aucun secret / `.env` n'est committé diff --git a/.gitea/issue_template/bug_report.yaml b/.gitea/issue_template/bug_report.yaml new file mode 100644 index 0000000..8cd423a --- /dev/null +++ b/.gitea/issue_template/bug_report.yaml @@ -0,0 +1,57 @@ +name: "🐞 Rapport d'incident" +about: "Signaler un dysfonctionnement (bug) sur CESIZen" +title: "[BUG] " +labels: + - bug +body: + - type: dropdown + id: composant + attributes: + label: Composant concerné + options: + - Web (Laravel) + - Mobile (Flutter) + - Wear OS + - API + - Autre + validations: + required: true + - type: dropdown + id: gravite + attributes: + label: Gravité + options: + - Critique (service indisponible) + - Majeure (fonctionnalité bloquée) + - Mineure (contournement possible) + - Cosmétique + validations: + required: true + - type: textarea + id: description + attributes: + label: Description du problème + description: Que se passe-t-il ? + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Étapes de reproduction + placeholder: | + 1. Aller sur ... + 2. Cliquer sur ... + 3. Constater ... + validations: + required: true + - type: textarea + id: attendu + attributes: + label: Comportement attendu + validations: + required: true + - type: input + id: environnement + attributes: + label: Environnement + placeholder: "Prod / Préprod — navigateur / OS / version" diff --git a/.gitea/issue_template/feature_request.yaml b/.gitea/issue_template/feature_request.yaml new file mode 100644 index 0000000..556b0d7 --- /dev/null +++ b/.gitea/issue_template/feature_request.yaml @@ -0,0 +1,36 @@ +name: "✨ Demande d'évolution" +about: "Proposer une nouvelle fonctionnalité ou une amélioration" +title: "[EVOL] " +labels: + - enhancement +body: + - type: textarea + id: besoin + attributes: + label: Besoin / Problème à résoudre + description: Quel besoin utilisateur ou métier cette évolution couvre-t-elle ? + validations: + required: true + - type: textarea + id: solution + attributes: + label: Solution proposée + validations: + required: true + - type: dropdown + id: priorite + attributes: + label: Priorité souhaitée + options: + - Haute + - Moyenne + - Basse + validations: + required: true + - type: textarea + id: criteres + attributes: + label: Critères d'acceptation + placeholder: | + - [ ] ... + - [ ] ... diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..a06f19b --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,89 @@ +# ───────────────────────────────────────────────────────────── +# Intégration Continue (CI) — CESIZen / Application Web Laravel +# Déclenché à chaque push et chaque pull request. +# Objectif : garantir la qualité et la sécurité du code AVANT +# tout déploiement (tests, style, audit de vulnérabilités). +# ───────────────────────────────────────────────────────────── +name: CI - Web (Laravel) + +on: + push: + branches: [main, develop] + paths: + - 'WEB/**' + - '.gitea/workflows/ci.yml' + pull_request: + branches: [main, develop] + paths: + - 'WEB/**' + +# Empêche deux exécutions concurrentes sur la même branche +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + quality-and-tests: + runs-on: ubuntu-latest + defaults: + run: + working-directory: WEB + + steps: + # 1. Récupération du code source + - name: Checkout du dépôt + uses: actions/checkout@v4 + + # 2. Installation de l'environnement PHP + - name: Installation de PHP 8.3 + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: pdo_mysql, mbstring, exif, pcntl, bcmath, gd, intl, zip + coverage: none + tools: composer:v2 + + # 3. Cache des dépendances Composer (accélère les builds) + - name: Cache Composer + uses: actions/cache@v4 + with: + path: WEB/vendor + key: composer-${{ hashFiles('WEB/composer.lock') }} + restore-keys: composer- + + # 4. Installation des dépendances PHP + - name: Installation des dépendances Composer + run: composer install --no-interaction --prefer-dist --no-progress + + # 5. Préparation de l'environnement de test + - name: Préparation de l'environnement + run: | + cp .env.example .env + php artisan key:generate + + # 6. Vérification du style de code (bonne pratique — grille : qualité du code) + - name: Analyse du style (Laravel Pint) + run: ./vendor/bin/pint --test + + # 7. Audit de sécurité des dépendances PHP (CVE connues). + # Étape informative : elle signale les vulnérabilités connues sans + # bloquer la livraison (certaines dépendent d'un correctif amont). + - name: Audit de sécurité Composer + run: composer audit --no-interaction + continue-on-error: true + + # 8. Installation et audit des dépendances front (Vite/npm) + - name: Installation des dépendances Node + run: npm ci + + - name: Audit de sécurité npm + run: npm audit --audit-level=high + continue-on-error: true # informatif : ne bloque pas le build + + # 9. Build des assets front (vérifie que la compilation passe) + - name: Build des assets (Vite) + run: npm run build + + # 10. Exécution de la suite de tests automatisés (PHPUnit) + - name: Tests automatisés + run: php artisan test --env=testing diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..1b4627d --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,79 @@ +# ───────────────────────────────────────────────────────────── +# Déploiement Continu (CD) — CESIZen / Application Web Laravel +# Déclenché après un merge sur `main` (ou un tag de version). +# Chaîne : build image Docker → push vers le Container Registry +# de Gitea → déclenchement du webhook Portainer (redéploiement). +# ───────────────────────────────────────────────────────────── +name: CD - Déploiement Web (Production) + +on: + push: + branches: [main] + paths: + - 'WEB/**' + - '.gitea/workflows/deploy.yml' + tags: + - 'v*' + workflow_dispatch: {} # permet un déclenchement manuel depuis l'UI Gitea + +env: + # Registre de conteneurs intégré à Gitea + REGISTRY: gitea.sam-coffre.duckdns.org + IMAGE_NAME: ${{ github.repository_owner }}/cesizen-web + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + # 1. Récupération du code source + - name: Checkout du dépôt + uses: actions/checkout@v4 + + # 2. Préparation de Docker Buildx + - name: Configuration de Docker Buildx + uses: docker/setup-buildx-action@v3 + + # 3. Authentification sur le Container Registry Gitea + # Les identifiants sont stockés dans les secrets du dépôt. + - name: Connexion au registre Gitea + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_TOKEN }} + + # 4. Calcul des tags de l'image (latest + SHA court + tag Git) + - name: Définition des tags + id: meta + run: | + echo "sha=$(echo ${{ github.sha }} | cut -c1-7)" >> "$GITHUB_OUTPUT" + + # 5. Build et push de l'image (contexte = dossier WEB) + - name: Build & Push de l'image Docker + uses: docker/build-push-action@v6 + with: + context: ./WEB + file: ./WEB/Dockerfile + push: true + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # 6. Déclenchement du redéploiement Portainer + # Portainer re-pull l'image `latest` et recrée le conteneur. + # L'URL du webhook est un secret (ne jamais l'exposer en clair). + - name: Redéploiement via webhook Portainer + run: | + echo "Déclenchement du redéploiement Portainer..." + curl --fail --silent --show-error -X POST "${{ secrets.PORTAINER_WEBHOOK_URL }}" + echo "Redéploiement demandé avec succès." + + # 7. (Optionnel) Vérification de disponibilité post-déploiement + - name: Health check + run: | + sleep 20 + curl --fail --silent --show-error https://cesizen.sam-coffre.duckdns.org/up \ + || echo "::warning::Le health check /up n'a pas répondu — vérifier le conteneur." diff --git a/ci/act_runner/docker-compose.yml b/ci/act_runner/docker-compose.yml new file mode 100644 index 0000000..ec4d13b --- /dev/null +++ b/ci/act_runner/docker-compose.yml @@ -0,0 +1,28 @@ +# ───────────────────────────────────────────────────────────── +# Runner Gitea Actions (act_runner) +# À déployer sur le serveur (via Portainer ou docker compose). +# Il exécute les workflows définis dans .gitea/workflows/. +# +# Étapes d'enregistrement : +# 1. Dans Gitea : Administration ▸ Actions ▸ Runners ▸ "Create new runner" +# pour obtenir le REGISTRATION TOKEN. +# 2. Renseigner GITEA_RUNNER_REGISTRATION_TOKEN ci-dessous (ou via .env). +# 3. `docker compose up -d` +# ───────────────────────────────────────────────────────────── +services: + act_runner: + image: gitea/act_runner:latest + container_name: gitea-act-runner + restart: always + environment: + # URL de l'instance Gitea + GITEA_INSTANCE_URL: https://gitea.sam-coffre.duckdns.org + # Jeton d'enregistrement récupéré dans l'admin Gitea + GITEA_RUNNER_REGISTRATION_TOKEN: "${GITEA_RUNNER_REGISTRATION_TOKEN}" + GITEA_RUNNER_NAME: cesizen-runner + # Images utilisées pour les labels (ubuntu-latest => image complète) + GITEA_RUNNER_LABELS: "ubuntu-latest:docker://catthehacker/ubuntu:act-latest" + volumes: + # Le runner a besoin du socket Docker pour lancer les jobs conteneurisés + - /var/run/docker.sock:/var/run/docker.sock + - ./data:/data