name: Deploy (stellaamor)

on:
  push:
    branches: [ "main" ]   # change if you use main

jobs:
  deploy:
    runs-on: [ self-hosted, mainhost, docker ]
    concurrency:
      group: deploy-stellaamor
      cancel-in-progress: false

    env:
      # ---- required (set these as repo/org SECRETS) ----
      SSH_HOST: ${{ secrets.SSH_HOST }}        # e.g. 192.168.122.50 (the stellaamor VM)
      SSH_USER: ${{ secrets.SSH_USER }}        # e.g. deploy
      SSH_KEY:  ${{ secrets.SSH_KEY }}         # private key (ed25519), one line
      # optional but recommended: known_hosts entry for your VM
      SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}

      # ---- repo-scoped settings (safe to commit) ----
      APP_ROOT: /var/www/stellaamor                # base dir on the VM
      UPLOADS_DIR: uploads                         # relative to shared/
      KEEP_N: "5"                                  # how many releases to keep
      HEALTH_URL: https://stellaamor.com/    # simple GET should return 200
      SERVICE_RELOAD: "systemctl reload apache2 || true"

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

      # only build assets if you actually have a package.json with build script
      - name: Maybe build frontend (Vue/etc)
        if: hashFiles('package.json') != ''
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: npm ci
        if: hashFiles('package.json') != ''
        run: npm ci
      - name: npm build
        if: hashFiles('package.json') != ''
        run: npm run build

      - name: Prepare release tarball
        run: |
          set -euo pipefail
          REL="$(date -u +%Y%m%d-%H%M%SZ)-${{ github.sha }}"
          echo "REL=$REL" >> $GITHUB_ENV

          mkdir -p release
          # include everything except VCS, node dev dirs, and your uploads (they live in shared/)
          tar \
            --exclude-vcs \
            --exclude='./node_modules' \
            --exclude='./${{ env.UPLOADS_DIR }}' \
            -czf "release/${REL}.tar.gz" \
            .

      - name: Write SSH key
        run: |
          umask 077
          printf "%s" "${SSH_KEY}" > ~/.ssh/id_ed25519
          if [ -n "${SSH_KNOWN_HOSTS}" ]; then
            printf "%s\n" "${SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
          else
            # fall back only if you must (less secure)
            echo "StrictHostKeyChecking no" >> ~/.ssh/config
          fi

      - name: Upload & activate atomically
        run: |
          set -euo pipefail
          REL="${{ env.REL }}"
          TAR="release/${REL}.tar.gz"
          APP="${{ env.APP_ROOT }}"
          SHARED="${APP}/shared"
          RELEASES="${APP}/releases"
          CUR="${APP}/current"

          # ensure layout exists
          ssh -i ~/.ssh/id_ed25519 ${SSH_USER}@${SSH_HOST} "
            set -e
            sudo install -d -o ${SSH_USER} -g ${SSH_USER} -m 755 ${RELEASES} ${SHARED}
            sudo install -d -o ${SSH_USER} -g ${SSH_USER} -m 755 ${SHARED}/${{ env.UPLOADS_DIR }}
          "

          # upload tar
          scp -i ~/.ssh/id_ed25519 ${TAR} ${SSH_USER}@${SSH_HOST}:/tmp/${REL}.tar.gz

          # unpack to new release, link shared, write metadata, flip symlink, reload, health check
          ssh -i ~/.ssh/id_ed25519 ${SSH_USER}@${SSH_HOST} '
            set -euo pipefail
            REL="'${REL}'"; APP="'${APP}'"; SHARED="'${SHARED}'"; RELEASES="'${RELEASES}'"; CUR="'${CUR}'";

            NEW="${RELEASES}/${REL}"
            mkdir -p "${NEW}"
            tar -xzf "/tmp/${REL}.tar.gz" -C "${NEW}"
            rm -f "/tmp/${REL}.tar.gz"

            # link shared paths (uploads, env/config if you keep one there)
            rm -rf "${NEW}/${UPLOADS_DIR:-'${{ env.UPLOADS_DIR }}'}"
            ln -s "${SHARED}/${UPLOADS_DIR:-'${{ env.UPLOADS_DIR }}'}" "${NEW}/${UPLOADS_DIR:-'${{ env.UPLOADS_DIR }}'}"

            # optional: link a shared .env if you use one
            if [ -f "${SHARED}/.env" ]; then
              ln -sf "${SHARED}/.env" "${NEW}/.env"
            fi

            # metadata
            printf "sha=%s\nbuilt_at=%s\n" "'${{ github.sha }}'" "$(date -u +%FT%TZ)" > "${NEW}/RELEASE"

            # keep previous target for rollback
            PREV="$(readlink -f "${CUR}" || true)"
            ln -sfn "${NEW}" "${CUR}"

            # reload services
            '"${{ env.SERVICE_RELOAD }}"' >/dev/null 2>&1 || true

            # health check (simple GET)
            if command -v curl >/dev/null 2>&1; then
              curl -fsS --max-time 5 "'"${{ env.HEALTH_URL }}"'" >/dev/null || {
                echo "Health check failed, rolling back..."
                [ -n "${PREV}" ] && ln -sfn "${PREV}" "${CUR}" && '"${{ env.SERVICE_RELOAD }}"' >/dev/null 2>&1 || true
                exit 1
              }
            fi

            # prune old releases
            cd "${RELEASES}"
            ls -1tr | head -n -'${{ env.KEEP_N }}' | xargs -r -I{} rm -rf "{}"
          '

