name: Build & deploy image

# Workflow RÉUTILISABLE LOCAL (workflow_call) — copie vendorisée du framework
# WP Reactor (wp-reactor/wp-reactor/.github/workflows/build-and-deploy-image.yml).
# Vendorisé ici car un workflow réutilisable d'un repo PRIVÉ d'une autre org
# n'est pas accessible cross-org via le GITHUB_TOKEN. Appelé en local par
# deploy.yml via `uses: ./.github/workflows/build-and-deploy-image.yml`.
#
# L'appelant DOIT utiliser `secrets: inherit` : le job porte
# `environment: ${{ inputs.environment }}`, seul moyen de résoudre les secrets
# au niveau de l'environnement GitHub (`environment` est interdit sur un job
# qui appelle un workflow réutilisable).

on:
  workflow_call:
    inputs:
      environment:
        description: "Environnement GitHub portant les secrets (production | staging)."
        required: true
        type: string
      image:
        description: "Référence image sans tag (ex. ghcr.io/owner/repo/webapp)."
        required: true
        type: string
      dockerfile:
        description: "Chemin du Dockerfile."
        required: true
        type: string
      context:
        description: "Contexte de build Docker."
        required: false
        type: string
        default: "."
      target:
        description: "Stage cible du Dockerfile (optionnel)."
        required: false
        type: string
        default: ""
      build-args:
        description: "Build-args multilignes (KEY=VALUE par ligne)."
        required: false
        type: string
        default: ""
      coolify-uuid-secret:
        description: "Nom du secret d'environnement portant l'UUID Coolify (ex. COOLIFY_WEBAPP_UUID). Vide = pas de redéploiement."
        required: false
        type: string
        default: ""
      coolify-resource:
        description: "Type de ressource Coolify visée : application (défaut) ou service (ressource Docker Compose)."
        required: false
        type: string
        default: "application"
      runs-on:
        description: "Runner."
        required: false
        type: string
        default: "ubuntu-latest"

jobs:
  build-and-push:
    runs-on: ${{ inputs.runs-on }}
    environment: ${{ inputs.environment }}
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4

      - name: Image en minuscules & tags
        id: img
        env:
          IMAGE: ${{ inputs.image }}
        run: |
          ref=$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]')
          {
            echo "tags<<EOF"
            echo "${ref}:${GITHUB_REF_NAME}"
            echo "${ref}:${GITHUB_SHA}"
            # `latest` reste réservé à la production.
            if [ "${GITHUB_REF_NAME}" = "main" ]; then echo "${ref}:latest"; fi
            echo "EOF"
          } >> "$GITHUB_OUTPUT"

      - uses: docker/setup-buildx-action@v3

      - name: Login GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build & push
        uses: docker/build-push-action@v6
        with:
          context: ${{ inputs.context }}
          file: ${{ inputs.dockerfile }}
          target: ${{ inputs.target }}
          push: true
          tags: ${{ steps.img.outputs.tags }}
          build-args: |
            ${{ inputs.build-args }}
            NODE_AUTH_TOKEN=${{ secrets.NODE_AUTH_TOKEN }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Redeploy Coolify (si configuré)
        env:
          COOLIFY_URL: ${{ secrets.COOLIFY_URL }}
          COOLIFY_TOKEN: ${{ secrets.COOLIFY_TOKEN }}
          COOLIFY_UUID: ${{ inputs.coolify-uuid-secret != '' && secrets[inputs.coolify-uuid-secret] || '' }}
          COOLIFY_RESOURCE: ${{ inputs.coolify-resource }}
        if: ${{ env.COOLIFY_URL != '' && env.COOLIFY_TOKEN != '' && env.COOLIFY_UUID != '' }}
        run: |
          # Une ressource Compose ne re-tire PAS l'image sur /api/v1/deploy :
          # Coolify y lance StartService sans `docker compose pull`, donc le tag
          # mutable (:main / :development) déjà sur l'hôte est réutilisé et le
          # conteneur redémarre sur l'image de la veille. `force` ne concerne que
          # les applications. Seul /services/{uuid}/restart?latest=true pull.
          base="${COOLIFY_URL%/}"
          if [ "${COOLIFY_RESOURCE}" = "service" ]; then
            curl --fail --silent --show-error --request POST \
              "${base}/api/v1/services/${COOLIFY_UUID}/restart?latest=true" \
              --header "Authorization: Bearer ${COOLIFY_TOKEN}"
          else
            curl --fail --silent --show-error --request GET \
              "${base}/api/v1/deploy?uuid=${COOLIFY_UUID}&force=true" \
              --header "Authorization: Bearer ${COOLIFY_TOKEN}"
          fi
