diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 51e28d5..7b41dfb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,7 @@ stages: - build + - deploy + - notify variables: # OVH Container Registry URL (without https://) @@ -37,3 +39,264 @@ build: - echo " - $IMAGE_LATEST" after_script: - docker logout $OVH_REGISTRY_URL || true + +deploy: + stage: deploy + image: alpine:latest + needs: + - build + rules: + - if: '$CI_COMMIT_BRANCH == "develop"' + when: on_success + - when: manual + before_script: + - apk add --no-cache openssh-client + - mkdir -p ~/.ssh + - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - echo "Host *\n StrictHostKeyChecking no\n UserKnownHostsFile=/dev/null" > ~/.ssh/config + - chmod 600 ~/.ssh/config + - ssh-keyscan -H $SERVER_IP >> ~/.ssh/known_hosts || true + script: + - | + ssh $SSH_USER@$SERVER_IP << ENDSSH + set -e + cd /mnt/external-disk/easy-monitor/easyportal + + # ===== PRE-DEPLOYMENT DOCKER CLEANUP ===== + echo '===== Starting pre-deployment Docker cleanup =====' + + # Show current Docker space usage + echo 'Current Docker space usage:' + docker system df + + # Clean build cache + echo 'Cleaning Docker build cache...' + docker builder prune -f || true + + # Clean stopped containers + echo 'Cleaning stopped containers...' + docker container prune -f || true + + # Clean unused networks + echo 'Cleaning unused networks...' + docker network prune -f || true + + # Show space usage after cleanup + echo 'Docker space usage after initial cleanup:' + docker system df + + # Login to OVH registry + echo "$OVH_REGISTRY_PASSWORD" | docker login -u "$OVH_REGISTRY_USERNAME" "$OVH_REGISTRY_URL" --password-stdin + + # Pull latest image + echo 'Pulling latest image...' + docker pull $IMAGE_LATEST + + # Clean unused images before deployment + echo 'Cleaning unused Docker images...' + docker image prune -f || true + + # Update .env.compose with new image tag + echo 'Updating .env.compose with new image...' + echo "EASYPORTAL_IMAGE=$IMAGE_LATEST" > .env.compose + + # Recreate php and messenger containers with new image + echo 'Restarting EasyPortal services with new image...' + docker compose --env-file .env.compose up -d --force-recreate --no-deps php messenger + + # Wait for service to be ready + sleep 15 + + # Run migrations + echo 'Running database migrations...' + docker compose --env-file .env.compose exec -T php php bin/console doctrine:migrations:migrate --no-interaction + + # Clear cache + echo 'Clearing Symfony cache...' + docker compose --env-file .env.compose exec -T php php bin/console cache:clear --env=prod --no-debug + + # ===== POST-DEPLOYMENT CLEANUP ===== + echo '===== Final Docker cleanup =====' + + docker builder prune -f || true + docker container prune -f || true + + # Keep last 3 image versions + echo 'Cleaning old image versions (keeping last 3)...' + docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}' | grep -v REPOSITORY | sort -k1,1 -k4,4r | awk ' + { + repo_tag = \$1":" \$2 + if (repo_count[\$1]++ >= 3 && \$2 != "latest" && \$1 != "") { + print \$3 + } + }' | xargs -r docker rmi -f || true + + echo 'Final Docker space usage:' + docker system df + + echo '===== Deployment completed successfully! =====' + ENDSSH + after_script: + - rm -f ~/.ssh/id_rsa + environment: + name: production + url: https://testportail.solutions-easy.com + +notify_success: + stage: notify + image: curlimages/curl:latest + needs: + - deploy + rules: + - when: on_success + - when: manual + allow_failure: true + script: + - | + COMMIT_SHORT_SHA=$(echo $CI_COMMIT_SHA | cut -c1-8) + DEPLOYMENT_TYPE="Déploiement Beta" + + if [ "$CI_COMMIT_BRANCH" != "develop" ]; then + DEPLOYMENT_TYPE="Déploiement Beta" + fi + + curl -H "Content-Type: application/json" -d "{ + \"type\": \"message\", + \"attachments\": [ + { + \"contentType\": \"application/vnd.microsoft.card.adaptive\", + \"content\": { + \"type\": \"AdaptiveCard\", + \"body\": [ + { + \"type\": \"TextBlock\", + \"text\": \"$DEPLOYMENT_TYPE\", + \"weight\": \"Bolder\", + \"size\": \"Large\" + }, + { + \"type\": \"TextBlock\", + \"text\": \"**App:** EasyPortal\", + \"wrap\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Version:** [$CI_COMMIT_REF_NAME - $COMMIT_SHORT_SHA]($CI_PROJECT_URL/-/commit/$CI_COMMIT_SHA)\", + \"wrap\": true, + \"markdown\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Pipeline:** [Voir le pipeline]($CI_PIPELINE_URL)\", + \"wrap\": true, + \"markdown\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Auteur:** $GITLAB_USER_LOGIN\", + \"wrap\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Statut:** Succès ✓\", + \"wrap\": true, + \"color\": \"Good\" + } + ], + \"actions\": [ + { + \"type\": \"Action.OpenUrl\", + \"title\": \"Voir le pipeline\", + \"url\": \"$CI_PIPELINE_URL\" + }, + { + \"type\": \"Action.OpenUrl\", + \"title\": \"Voir le commit\", + \"url\": \"$CI_PROJECT_URL/-/commit/$CI_COMMIT_SHA\" + } + ], + \"\$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\", + \"version\": \"1.0\" + } + } + ] + }" "$TEAMS_WEBHOOK_URL" + +notify_failure: + stage: notify + image: curlimages/curl:latest + needs: + - deploy + rules: + - when: on_failure + script: + - | + COMMIT_SHORT_SHA=$(echo $CI_COMMIT_SHA | cut -c1-8) + DEPLOYMENT_TYPE="Déploiement Beta" + + if [ "$CI_COMMIT_BRANCH" != "develop" ]; then + DEPLOYMENT_TYPE="Déploiement Beta" + fi + + curl -H "Content-Type: application/json" -d "{ + \"type\": \"message\", + \"attachments\": [ + { + \"contentType\": \"application/vnd.microsoft.card.adaptive\", + \"content\": { + \"type\": \"AdaptiveCard\", + \"body\": [ + { + \"type\": \"TextBlock\", + \"text\": \"$DEPLOYMENT_TYPE\", + \"weight\": \"Bolder\", + \"size\": \"Large\" + }, + { + \"type\": \"TextBlock\", + \"text\": \"**App:** EasyPortal\", + \"wrap\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Version:** [$CI_COMMIT_REF_NAME - $COMMIT_SHORT_SHA]($CI_PROJECT_URL/-/commit/$CI_COMMIT_SHA)\", + \"wrap\": true, + \"markdown\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Pipeline:** [Voir le pipeline]($CI_PIPELINE_URL)\", + \"wrap\": true, + \"markdown\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Auteur:** $GITLAB_USER_LOGIN\", + \"wrap\": true + }, + { + \"type\": \"TextBlock\", + \"text\": \"**Statut:** Échec ✗\", + \"wrap\": true, + \"color\": \"Attention\" + } + ], + \"actions\": [ + { + \"type\": \"Action.OpenUrl\", + \"title\": \"Voir le pipeline\", + \"url\": \"$CI_PIPELINE_URL\" + }, + { + \"type\": \"Action.OpenUrl\", + \"title\": \"Voir le commit\", + \"url\": \"$CI_PROJECT_URL/-/commit/$CI_COMMIT_SHA\" + } + ], + \"\$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\", + \"version\": \"1.0\" + } + } + ] + }" "$TEAMS_WEBHOOK_URL"