From 103262a58245fdd7cf21fe62dfa760c2392abbce Mon Sep 17 00:00:00 2001 From: Ploush Date: Sun, 7 Jun 2026 12:00:04 +0200 Subject: [PATCH] Migration to forgejo + New CICD --- .dockerignore | 2 +- .forgejo/workflows/deploy.yml | 137 ++++++++++++++++++++++++++++++++++ .github/workflows/deploy.yml | 39 ---------- app/src/Form/Mod/ModType.php | 2 +- docker/apache/Dockerfile | 3 +- docker/apache/php.ini | 14 ++++ 6 files changed, 155 insertions(+), 42 deletions(-) create mode 100644 .forgejo/workflows/deploy.yml delete mode 100644 .github/workflows/deploy.yml create mode 100644 docker/apache/php.ini diff --git a/.dockerignore b/.dockerignore index 33afe3b..97d8bd5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -55,7 +55,7 @@ docker-compose*.yaml .dockerignore # CI/CD -.github/ +.forgejo/ .gitlab-ci.yml .travis.yml diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml new file mode 100644 index 0000000..1b1d5b4 --- /dev/null +++ b/.forgejo/workflows/deploy.yml @@ -0,0 +1,137 @@ +# ============================================================ +# Forgejo Actions — Build + Push image → Registre Forgejo +# Déclenché uniquement sur un tag A.B.C poussé sur main +# ============================================================ +# +# Prérequis : créer un jeton Forgejo dans +# Paramètres → Applications → Jetons d'accès personnel +# Permissions requises : read:packages, write:packages +# Puis l'ajouter dans le dépôt : +# Paramètres → Actions → Secrets → FORGEJO_TOKEN +# ============================================================ + +name: Build & Deploy + +on: + push: + tags: + # Pré-filtre glob (validation stricte faite dans le job) + - '[1-9]*.[1-9]*.[1-9]*' + +jobs: + build-and-push: + name: Validation, build et push + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + + # ── 1. Checkout complet (historique + tags) ─────────────────────── + - name: Checkout du code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Indispensable pour comparer les tags existants + + # ── 2. Le tag doit pointer sur un commit présent dans main ───────── + - name: Vérification — tag sur main + run: | + git fetch origin main --no-tags + + if ! git merge-base --is-ancestor "${{ github.sha }}" origin/main; then + echo "❌ Le tag '${{ github.ref_name }}' ne pointe pas sur un commit de main." + exit 1 + fi + + echo "✅ Commit du tag présent dans main." + + # ── 3. Validation du format + progression de version ────────────── + - name: Validation du tag et calcul des tags Docker + id: semver + run: | + TAG="${{ github.ref_name }}" + + # ── Format strict : A.B.C avec A, B, C entiers > 0 ────────── + if ! echo "$TAG" | grep -qE '^[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*$'; then + echo "❌ Format invalide : '$TAG'" + echo " Attendu : A.B.C avec A, B, C entiers > 0 (ex: 1.2.3)" + exit 1 + fi + + IFS='.' read -r A B C <<< "$TAG" + + # ── Trouver le tag valide le plus élevé (hors tag courant) ─── + # Les tags sont triés numériquement par composant : le dernier + # de la boucle est donc le maximum courant. + PREV_TAG="" + while IFS= read -r t; do + [ "$t" = "$TAG" ] && continue + if echo "$t" | grep -qE '^[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*$'; then + PREV_TAG="$t" + fi + done < <(git tag -l | sort -t. -k1,1n -k2,2n -k3,3n) + + # ── Vérification de la progression stricte ─────────────────── + if [ -n "$PREV_TAG" ]; then + IFS='.' read -r PA PB PC <<< "$PREV_TAG" + echo "ℹ️ Tag précédent le plus élevé : $PREV_TAG" + + OK=false + if [ "$A" -gt "$PA" ]; then + OK=true + elif [ "$A" -eq "$PA" ] && [ "$B" -gt "$PB" ]; then + OK=true + elif [ "$A" -eq "$PA" ] && [ "$B" -eq "$PB" ] && [ "$C" -gt "$PC" ]; then + OK=true + fi + + if [ "$OK" = false ]; then + echo "❌ '$TAG' ne respecte pas la règle de progression :" + echo " A > PA" + echo " OU ( A = PA ET B > PB )" + echo " OU ( A = PA ET B = PB ET C > PC )" + echo " Tag précédent : $PREV_TAG — Tag proposé : $TAG" + exit 1 + fi + else + echo "ℹ️ Aucun tag valide précédent — première version, pas de vérification de progression." + fi + + echo "✅ Tag '$TAG' validé." + + # ── Outputs réutilisés par les étapes suivantes ─────────────── + echo "full=${A}.${B}.${C}" >> "$GITHUB_OUTPUT" + echo "minor=${A}.${B}" >> "$GITHUB_OUTPUT" + echo "major=${A}" >> "$GITHUB_OUTPUT" + + # ── 4. Extraction du hostname du registre Forgejo ───────────────── + - name: Extraction de l'URL du registre + id: registry + run: | + # Retire le protocole pour obtenir uniquement le hostname + # Ex : https://forge.example.com → forge.example.com + HOST=$(echo "${{ github.server_url }}" | sed -E 's|^https?://||') + echo "host=${HOST}" >> "$GITHUB_OUTPUT" + + # ── 5. Authentification ─────────────────────────────────────────── + - name: Connexion au registre Forgejo + uses: docker/login-action@v3 + with: + registry: ${{ steps.registry.outputs.host }} + username: ${{ github.actor }} + password: ${{ secrets.FORGEJO_TOKEN }} + + # ── 6. Build et push (4 tags) ───────────────────────────────────── + - name: Build et push de l'image Docker + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/apache/Dockerfile + push: true + tags: | + ${{ steps.registry.outputs.host }}/${{ github.repository_owner }}/mcserverwebsite:${{ steps.semver.outputs.full }} + ${{ steps.registry.outputs.host }}/${{ github.repository_owner }}/mcserverwebsite:${{ steps.semver.outputs.minor }} + ${{ steps.registry.outputs.host }}/${{ github.repository_owner }}/mcserverwebsite:${{ steps.semver.outputs.major }} + ${{ steps.registry.outputs.host }}/${{ github.repository_owner }}/mcserverwebsite:latest \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 7d97e6f..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,39 +0,0 @@ -# ============================================================ -# GitHub Actions — Build + Push image → GHCR -# Déclenche un redéploiement automatique via webhook Portainer -# ============================================================ - -name: Build & Deploy - -on: - push: - branches: - - master - -jobs: - build-and-push: - name: Build image et push sur GHCR - runs-on: ubuntu-latest - - permissions: - contents: read - packages: write # Nécessaire pour pousser sur ghcr.io - - steps: - - name: Checkout du code - uses: actions/checkout@v4 - - - name: Connexion au GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} # Automatique, rien à configurer - - - name: Build et push de l'image Docker - uses: docker/build-push-action@v5 - with: - context: . - file: ./docker/apache/Dockerfile - push: true - tags: ghcr.io/${{ github.repository_owner }}/mcserverwebsite:latest \ No newline at end of file diff --git a/app/src/Form/Mod/ModType.php b/app/src/Form/Mod/ModType.php index 7e8cfd3..103f2fd 100644 --- a/app/src/Form/Mod/ModType.php +++ b/app/src/Form/Mod/ModType.php @@ -46,7 +46,7 @@ class ModType extends AbstractType ->add('uri', FileType::class, [ 'disabled' => $isEdit, 'mapped' => false, - 'label' => 'URL du mod', + 'label' => 'Fichier', 'constraints' => [ new Assert\File([ 'maxSize' => '128M', diff --git a/docker/apache/Dockerfile b/docker/apache/Dockerfile index c7bf229..bad039c 100644 --- a/docker/apache/Dockerfile +++ b/docker/apache/Dockerfile @@ -46,7 +46,8 @@ RUN mkdir -p /var/www/html/var \ && chown -R www-data:www-data /var/www/html \ && chmod -R 755 /var/www/html/var -# ── Config OPcache ─────────────────────────────────────── +# ── Config PHP ─────────────────────────────────────────── +COPY docker/apache/php.ini /usr/local/etc/php/conf.d/custom.ini COPY docker/apache/opcache.ini /usr/local/etc/php/conf.d/opcache.ini # ── Config Apache ──────────────────────────────────────────── diff --git a/docker/apache/php.ini b/docker/apache/php.ini new file mode 100644 index 0000000..5d5d8bd --- /dev/null +++ b/docker/apache/php.ini @@ -0,0 +1,14 @@ +; Configuration PHP pour Symfony + +; Limites de fichiers (pour les uploads de fichiers JAR volumineux) +upload_max_filesize = 128M +post_max_size = 128M +memory_limit = 256M + +; Timeouts (utile pour les gros uploads) +max_execution_time = 300 +max_input_time = 300 + +; Sessions +session.gc_maxlifetime = 86400 +