name: Laravel CI-CD

on:
  push:
    branches: ["main"]

env:
  KAMAL_IMAGE: ghcr.io/basecamp/kamal:v2.11.0

jobs:
  test:
    name: Tests Unitaires
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Run Tests
        uses: docker://laravelsail/php84-composer:latest
        env:
          APP_ENV: testing
          APP_KEY: base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
          DB_CONNECTION: sqlite
          DB_DATABASE: ":memory:"
        with:
          args: >
            bash -lc "apt-get update
            && apt-get install -y --no-install-recommends libicu-dev
            && docker-php-ext-install intl
            && php -m | grep -qi '^intl$'
            && composer install --no-interaction --prefer-dist
            && php -d memory_limit=512M artisan test --compact"

  deploy:
    name: Deploy with Kamal
    needs: test
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Deploy
        env:
          GITEA_TOKEN: ${{ secrets.TOKEN_GITEA }}
          APP_KEY: ${{ secrets.APP_KEY }}
          DB_DATABASE: ${{ secrets.DB_DATABASE }}
          DB_USERNAME: ${{ secrets.DB_USERNAME }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
          MEILISEARCH_KEY: ${{ secrets.MEILISEARCH_KEY }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
          STRIPE_KEY: ${{ secrets.STRIPE_KEY }}
          STRIPE_SECRET: ${{ secrets.STRIPE_SECRET }}
          STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }}
          SSH_HOST: ${{ secrets.SSH_HOST }}
          SSH_USER: ${{ secrets.SSH_USER }}
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }}
          STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }}
          RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

        run: |
          set -eu
          : "${GEMINI_API_KEY:?GEMINI_API_KEY secret is required}"
          : "${STRIPE_KEY:?STRIPE_KEY secret is required}"
          : "${STRIPE_SECRET:?STRIPE_SECRET secret is required}"
          : "${STRIPE_WEBHOOK_SECRET:?STRIPE_WEBHOOK_SECRET secret is required}"
          : "${AWS_ACCESS_KEY_ID:?AWS_ACCESS_KEY_ID secret is required}"
          : "${AWS_SECRET_ACCESS_KEY:?AWS_SECRET_ACCESS_KEY secret is required}"

          WORKSPACE="${GITHUB_WORKSPACE:-$PWD}"
          test -f "$WORKSPACE/config/deploy.yml"

          tar \
            --exclude=.kamal/secrets \
            --exclude=.kamal/secrets.* \
            --exclude=.env \
            --exclude=.env.* \
            -C "$WORKSPACE" -cf - . | docker run --rm -i \
            -v /var/run/docker.sock:/var/run/docker.sock \
            -e GITEA_TOKEN \
            -e APP_KEY \
            -e DB_DATABASE \
            -e DB_USERNAME \
            -e DB_PASSWORD \
            -e MEILISEARCH_KEY \
            -e GEMINI_API_KEY \
            -e STRIPE_KEY \
            -e STRIPE_SECRET \
            -e STRIPE_WEBHOOK_SECRET \
            -e SSH_HOST \
            -e SSH_USER \
            -e SSH_PRIVATE_KEY \
            -e STRAVA_CLIENT_ID \
            -e STRAVA_CLIENT_SECRET \
            -e RESEND_API_KEY \
            -e AWS_ACCESS_KEY_ID \
            -e AWS_SECRET_ACCESS_KEY \
            --entrypoint /bin/sh \
            "$KAMAL_IMAGE" -lc '
              set -eu

              mkdir -p /workdir /root/.ssh
              tar -xf - -C /workdir
              cd /workdir

              chmod 700 /root/.ssh
              printf "%s\n" "$SSH_PRIVATE_KEY" | tr -d "\r" > /root/.ssh/id_ed25519
              chmod 600 /root/.ssh/id_ed25519

              REMOTE_HOST="${SSH_HOST:-89.167.35.217}"
              REMOTE_USER="${SSH_USER:-root}"

              mkdir -p /workdir/.ssh
              cat > /workdir/.ssh/config <<'"'"'SSH_CONFIG'"'"'
          Host *
            IdentityFile /root/.ssh/id_ed25519
            IdentitiesOnly yes
            StrictHostKeyChecking yes
            UserKnownHostsFile /workdir/.ssh/known_hosts
            GlobalKnownHostsFile /dev/null
            CheckHostIP no
          SSH_CONFIG
              ssh-keyscan -H "$REMOTE_HOST" > /workdir/.ssh/known_hosts
              chmod 600 /workdir/.ssh/config /workdir/.ssh/known_hosts

              mkdir -p .kamal
              cat > .kamal/secrets <<'"'"'SECRETS'"'"'
          GITEA_TOKEN=$GITEA_TOKEN
          APP_KEY=$APP_KEY
          DB_DATABASE=$DB_DATABASE
          DB_USERNAME=$DB_USERNAME
          DB_PASSWORD=$DB_PASSWORD
          MEILISEARCH_KEY=$MEILISEARCH_KEY
          GEMINI_API_KEY=$GEMINI_API_KEY
          STRIPE_KEY=$STRIPE_KEY
          STRIPE_SECRET=$STRIPE_SECRET
          STRIPE_WEBHOOK_SECRET=$STRIPE_WEBHOOK_SECRET
          SSH_PRIVATE_KEY=$SSH_PRIVATE_KEY
          STRAVA_CLIENT_ID=$STRAVA_CLIENT_ID
          STRAVA_CLIENT_SECRET=$STRAVA_CLIENT_SECRET
          RESEND_API_KEY=$RESEND_API_KEY
          AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
          AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
          SECRETS
              chmod 600 .kamal/secrets

              ssh -F /workdir/.ssh/config "$REMOTE_USER@$REMOTE_HOST" <<'"'"'REMOTE'"'"'
          set -eu

          docker network inspect bemeal_public >/dev/null 2>&1 || docker network create bemeal_public
          docker network inspect bemeal_internal >/dev/null 2>&1 || docker network create bemeal_internal

          for container in bemeal-pgsql bemeal-redis bemeal-meilisearch bemeal-adminer; do
            if docker inspect "$container" >/dev/null 2>&1; then
              docker network connect bemeal_internal "$container" >/dev/null 2>&1 || true
            fi
          done
          REMOTE

              /kamal/bin/kamal deploy
            '
