name: Deployment CI/CD on: push: branches: [main] pull_request: branches: [main] permissions: contents: read jobs: validate: runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 - name: Prepare local validation layout run: | cp .env.example .env mkdir -p backend/guilan-ace-backend frontend/guilan-ace-frontend cat <<'EOF' > backend/guilan-ace-backend/.env DJANGO_SETTINGS_MODULE=config.settings.production SECRET_KEY=validate DEBUG=False ALLOWED_HOSTS=api.example.com DJANGO_HOST=https://api.example.com DB_ENGINE=django.db.backends.postgresql DB_NAME=app DB_USER=app DB_PASSWORD=password DB_HOST=db DB_PORT=5432 REDIS_PASSWORD=password REDIS_URL=redis://:password@redis:6379/0 CELERY_BROKER_URL=redis://:password@redis:6379/0 CELERY_RESULT_BACKEND=redis://:password@redis:6379/1 EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend EMAIL_HOST=localhost EMAIL_PORT=587 EMAIL_USE_TLS=False EMAIL_HOST_USER= EMAIL_HOST_PASSWORD= DEFAULT_FROM_EMAIL=noreply@example.com JWT_SECRET_KEY=validate JWT_ALGORITHM=HS256 JWT_ACCESS_TOKEN_LIFETIME=3600 JWT_REFRESH_TOKEN_LIFETIME=86400 CORS_ALLOWED_ORIGINS=https://frontend.example.com FRONTEND_ROOT=https://frontend.example.com FRONTEND_PASSWORD_RESET_PAGE=https://frontend.example.com/reset-password FRONTEND_CALLBACK_URL=https://frontend.example.com/payments/result ZARINPAL_MERCHANT_ID=test ZARINPAL_USE_SANDBOX=True ZARINPAL_CALLBACK_URL=https://api.example.com/api/payments/callback GUNICORN_WORKERS=2 GUNICORN_THREADS=2 GUNICORN_TIMEOUT=120 EOF cat <<'EOF' > frontend/guilan-ace-frontend/.env VITE_API_BASE_URL=https://api.example.com EOF - name: Validate compose config run: docker compose config deploy: runs-on: ubuntu-latest needs: validate if: github.event_name == 'push' && github.ref == 'refs/heads/main' timeout-minutes: 30 steps: - name: Deploy compose stack uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} port: ${{ secrets.DEPLOY_PORT }} script: | set -e cd "${{ secrets.DEPLOY_PATH }}" git fetch --prune origin git checkout "${{ vars.DEPLOY_BRANCH || 'main' }}" git pull --ff-only origin "${{ vars.DEPLOY_BRANCH || 'main' }}" docker compose up -d --build --remove-orphans docker image prune -f