name: Deploy Production

on:
  workflow_dispatch:
    inputs:
      image_tag:
        description: Image tag to promote to production, for example sha-<commit>
        required: true
        type: string

permissions:
  contents: read

jobs:
  deploy:
    name: Deploy To Production
    runs-on: ubuntu-latest
    environment: production
    timeout-minutes: 30
    concurrency:
      group: deploy-production
      cancel-in-progress: false
    steps:
      - uses: actions/checkout@v4

      - id: vars
        name: Resolve image refs
        run: |
          owner="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
          repo="$(basename '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')"
          image_tag="${{ inputs.image_tag }}"
          echo "app_image=ghcr.io/${owner}/${repo}-app:${image_tag}" >> "$GITHUB_OUTPUT"
          echo "migrator_image=ghcr.io/${owner}/${repo}-migrator:${image_tag}" >> "$GITHUB_OUTPUT"

      - name: Prepare SSH
        env:
          SSH_PRIVATE_KEY: ${{ secrets.PROD_SSH_KEY }}
          SSH_HOST: ${{ secrets.PROD_SSH_HOST }}
          SSH_PORT: ${{ secrets.PROD_SSH_PORT }}
        run: |
          install -m 700 -d ~/.ssh
          printf '%s\n' "${SSH_PRIVATE_KEY}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -p "${SSH_PORT:-22}" -H "${SSH_HOST}" >> ~/.ssh/known_hosts

      - name: Bundle deploy assets
        run: tar czf deploy-bundle.tgz docker-compose.prod.yml tooling/deploy

      - name: Copy deploy assets to production
        env:
          SSH_PORT: ${{ secrets.PROD_SSH_PORT }}
        run: |
          ssh -p "${SSH_PORT:-22}" "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}" \
            "mkdir -p '${{ secrets.PROD_DEPLOY_PATH }}'"
          scp -P "${SSH_PORT:-22}" deploy-bundle.tgz \
            "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}:${{ secrets.PROD_DEPLOY_PATH }}/deploy-bundle.tgz"

      - name: Run production deployment
        env:
          APP_IMAGE: ${{ steps.vars.outputs.app_image }}
          MIGRATOR_IMAGE: ${{ steps.vars.outputs.migrator_image }}
          APP_HOST_PORT: ${{ secrets.PROD_APP_HOST_PORT }}
          GHCR_USERNAME: ${{ secrets.PROD_GHCR_USERNAME }}
          GHCR_TOKEN: ${{ secrets.PROD_GHCR_TOKEN }}
          SSH_PORT: ${{ secrets.PROD_SSH_PORT }}
        run: |
          cat > deploy.env <<EOF
          APP_IMAGE=${APP_IMAGE}
          MIGRATOR_IMAGE=${MIGRATOR_IMAGE}
          APP_HOST_PORT=${APP_HOST_PORT}
          GHCR_USERNAME=${GHCR_USERNAME}
          GHCR_TOKEN=${GHCR_TOKEN}
          EOF
          scp -P "${SSH_PORT:-22}" deploy.env \
            "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}:${{ secrets.PROD_DEPLOY_PATH }}/deploy.env"
          ssh -p "${SSH_PORT:-22}" "${{ secrets.PROD_SSH_USER }}@${{ secrets.PROD_SSH_HOST }}" 'bash -se' <<'EOF'
          set -euo pipefail
          cd "${{ secrets.PROD_DEPLOY_PATH }}"
          tar xzf deploy-bundle.tgz
          rm -f deploy-bundle.tgz
          set -a
          . ./deploy.env
          set +a
          bash tooling/deploy/deploy-compose.sh production
          rm -f deploy.env
          EOF
