name: Deploy Production on: push: tags: - "v*.*.*" workflow_dispatch: inputs: ref: description: "Tag a deployer (ex: v1.2.3)" required: true permissions: contents: read concurrency: group: deploy-prod cancel-in-progress: false jobs: deploy: name: Deploy to production runs-on: ubuntu-latest environment: production # required reviewers configures GitHub UI steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.inputs.ref || github.ref_name }} - name: Validate compose configs run: docker compose -f compose.yml -f compose.prod.yml config > /dev/null - name: Deploy via SSH uses: appleboy/ssh-action@v1 with: host: ${{ secrets.PROD_HOST }} username: ${{ secrets.PROD_USER }} key: ${{ secrets.PROD_SSH_KEY }} script_stop: true script: | set -euo pipefail cd /opt/formation-hub git fetch --tags git checkout ${{ github.event.inputs.ref || github.ref_name }} docker compose -f compose.yml -f compose.prod.yml pull docker compose -f compose.yml -f compose.prod.yml up -d ./scripts/healthcheck.sh - name: Smoke test run: | set -euo pipefail curl -fsS --max-time 10 ${{ secrets.PROD_URL }}/api/health || exit 1 - name: Watch logs (5 min) run: | # Optionnel : monitor logs apres deploy echo "Post-deploy watch — verifier monitoring/alerts pendant 30 min" - name: Notify on success if: success() uses: slackapi/slack-github-action@v1 with: payload: | { "text": "PROD deployed: ${{ github.event.inputs.ref || github.ref_name }} — sha ${{ github.sha }}" } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} continue-on-error: true - name: Notify on failure if: failure() uses: slackapi/slack-github-action@v1 with: payload: | { "text": "PROD deploy FAILED — ${{ github.event.inputs.ref || github.ref_name }}. Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} continue-on-error: true