name: 🚀 Deploy

on:
  push:
    branches:
      - main
      - dev

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions:
  actions: write
  contents: read
  packages: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v2

      - name: Get short SHA
        id: slug
        run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ steps.slug.outputs.sha8 }}

      - name: Deploy to server and clean up old images
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USERNAME }}
          # the private key
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin

            # Pull the new image
            docker pull ghcr.io/${{ github.repository }}:${{ steps.slug.outputs.sha8 }}

            # Stop and remove the old container
            docker stop yourappsname || true

            # Wait for the container to stop and then remove it
            for i in {1..10}; do
              if ! docker ps -q -f name=yourappsname | grep -q .; then
                docker rm yourappsname || true
                break
              fi
              echo "Waiting for container to stop..."
              sleep 2
            done

            # If the container is still running after 20 seconds, force remove it
            if docker ps -q -f name=yourappsname | grep -q .; then
              echo "Force removing container..."
              docker rm -f yourappsname || true
            fi

            # Run the new container
            docker run -d --restart unless-stopped --name yourappsname \
              --env-file /home/github/yourappsname.env \
              -p 3000:3000 \
              ghcr.io/${{ github.repository }}:${{ steps.slug.outputs.sha8 }}

            # Get the total number of images
            total_images=$(docker images ghcr.io/${{ github.repository }} -q | wc -l)

            # If there are 3 or fewer images, exit
            if [ $total_images -le 3 ]; then
              echo "There are 3 or fewer images. No images will be deleted."
              exit 0
            fi

            # Calculate how many images to delete
            to_delete=$((total_images - 3))

            # Get the image IDs to delete, sorted from newest to oldest
            images_to_delete=$(docker images ghcr.io/${{ github.repository }} --format '{{.CreatedAt}}\t{{.ID}}' | sort -r | tail -n +4 | cut -f2)

            # Delete the images
            for image in $images_to_delete; do
              docker rmi $image
            done

            echo "Deleted $to_delete images. The oldest 3 images have been kept."
  cleanup-packages:
    needs: deploy  # Run this after the deployment job
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Delete old packages
        uses: actions/delete-package-versions@v5
        with:
          package-name: 'yourappsname'
          package-type: 'container'
          min-versions-to-keep: 3