# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# SPDX-License-Identifier: GPL-3.0-or-later
# BRIEF: Build MokoGitea Docker image, push to registry, and deploy

name: Deploy MokoGitea

on:
  push:
    branches:
      - main
  workflow_dispatch:
    inputs:
      version:
        description: 'Version tag'
        required: true
        default: 'latest'
      environment:
        description: 'Target environment'
        required: true
        default: 'dev'
        type: choice
        options:
          - dev
          - production

concurrency:
  group: deploy-mokogitea
  cancel-in-progress: false

env:
  REGISTRY: git.mokoconsulting.tech
  IMAGE: mokoconsulting/mokogitea
  DEPLOY_HOST: git.mokoconsulting.tech
  DEPLOY_PORT: 2918
  DEPLOY_USER: mokoconsulting
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source (for version detection)
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Determine settings
        id: config
        run: |
          if [ "${{ github.event_name }}" = "push" ]; then
            VERSION=$(git describe --tags --always 2>/dev/null || echo "dev-$(git rev-parse --short HEAD)")
            ENV="production"
          else
            VERSION="${{ github.event.inputs.version }}"
            ENV="${{ github.event.inputs.environment }}"
          fi
          if [ "$ENV" = "production" ]; then
            echo "compose_dir=/opt/gitea" >> $GITHUB_OUTPUT
            echo "container=mokogitea" >> $GITHUB_OUTPUT
            echo "source_dir=/opt/gitea/source" >> $GITHUB_OUTPUT
            echo "branch=main" >> $GITHUB_OUTPUT
            echo "tag=$VERSION" >> $GITHUB_OUTPUT
          else
            echo "compose_dir=/opt/gitea-dev" >> $GITHUB_OUTPUT
            echo "container=mokogitea-dev" >> $GITHUB_OUTPUT
            echo "source_dir=/opt/gitea-dev/source" >> $GITHUB_OUTPUT
            echo "branch=dev" >> $GITHUB_OUTPUT
            echo "tag=$VERSION-dev" >> $GITHUB_OUTPUT
          fi

      - name: Write deploy key
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$DEPLOY_KEY" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key

      - name: Build and deploy via SSH
        env:
          REGISTRY_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
          TAG: ${{ steps.config.outputs.tag }}
          BRANCH: ${{ steps.config.outputs.branch }}
          SOURCE_DIR: ${{ steps.config.outputs.source_dir }}
          COMPOSE_DIR: ${{ steps.config.outputs.compose_dir }}
          CONTAINER: ${{ steps.config.outputs.container }}
        run: |
          HEALTH_FMT='${{ '{{' }}.State.Health.Status${{ '}}' }}'
          IMAGE_FMT='Image: ${{ '{{' }}.Config.Image${{ '}}' }}'

          ssh -i ~/.ssh/deploy_key -p ${{ env.DEPLOY_PORT }} \
            -o ConnectTimeout=30 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
            -o ServerAliveInterval=30 -o ServerAliveCountMax=10 \
            ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} bash -s <<DEPLOY_EOF
          set -e
          echo 'SSH connected'

          echo 'Cleaning Docker build cache...'
          docker builder prune -af 2>/dev/null || true
          docker image prune -af 2>/dev/null || true
          free -m | head -3

          echo 'Pulling source...'
          if [ ! -d $SOURCE_DIR/.git ]; then
            git clone -b $BRANCH https://git.mokoconsulting.tech/MokoConsulting/MokoGitea-Fork.git $SOURCE_DIR
          fi
          cd $SOURCE_DIR
          # Ensure remote points to MokoGitea-Fork (not the upstream fork)
          git remote set-url origin https://git.mokoconsulting.tech/MokoConsulting/MokoGitea-Fork.git 2>/dev/null || true
          git fetch origin $BRANCH
          git reset --hard origin/$BRANCH

          echo 'Building Docker image...'
          docker build --no-cache --build-arg GOFLAGS='-p 1' \
            --tag ${{ env.REGISTRY }}/${{ env.IMAGE }}:$TAG \
            --tag ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest \
            -f Dockerfile .

          echo 'Pushing to registry...'
          echo '$REGISTRY_TOKEN' | docker login ${{ env.REGISTRY }} -u ${{ env.DEPLOY_USER }} --password-stdin
          docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:$TAG
          docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest

          echo 'Restarting container...'
          cd $COMPOSE_DIR
          sed -i 's|${{ env.IMAGE }}:[^ ]*|${{ env.IMAGE }}:$TAG|' docker-compose.yml
          docker compose up -d $CONTAINER

          echo 'Health check...'
          for i in 1 2 3 4 5 6 7 8; do
            sleep 15
            if docker inspect --format='$HEALTH_FMT' $CONTAINER 2>/dev/null | grep -q healthy; then
              echo 'Container healthy!'
              docker inspect --format='$IMAGE_FMT' $CONTAINER
              exit 0
            fi
            echo "Waiting... (attempt \$i/8)"
          done
          echo 'Health check failed'
          docker logs $CONTAINER --tail 20
          exit 1
          DEPLOY_EOF

      - name: Verify
        run: |
          sleep 5
          curl -sf https://${{ env.DEPLOY_HOST }}/api/healthz && echo " API healthy"

      - name: Notify on failure
        if: failure()
        run: echo "::error::Deploy failed for ${{ steps.config.outputs.tag }}"
