name: Deploy

on:
  workflow_call:
    secrets:
      domain:
        description: Main project deploy domain used in URLs
        required: true
      payum-apikey:
        description: Payum API Key
        required: true
      storage-key:
        description: storage key
        required: true
      storage-secret-key:
        description: storage secret key
        required: true
      project-id:
        description: GCP project ID
        required: true
      workload-identity-provider:
        description: GCP workload identity provider
        required: true
      database-url:
        description: Database URL
        required: true
      mailer-dsn:
        description: Mailer DSN
        required: true
      sms-dsn:
        description: SMS DSN
        required: true


jobs:
  meta:
    name: Meta
    runs-on: ubuntu-latest
    outputs:
      context: ${{ steps.meta.outputs.context }}
      environment: ${{ steps.meta.outputs.environment }}
      image_tag: ${{ steps.meta.outputs.image_tag }}
      release_name: ${{ steps.meta.outputs.release_name }}
      url: ${{ steps.meta.outputs.url }}
      project: ${{ steps.meta.outputs.project }}
      namespace: ${{ steps.meta.outputs.namespace }}
      storage_name: ${{ steps.meta.outputs.storage_name }}
      trusted_host: ${{ steps.meta.outputs.trusted_host }}
    steps:
      - name: Generate metadata
        id: meta
        run: |
          set -xo pipefail
          PROJECT=tipimi-ebs
          # Tags are deployed in prod
          CONTEXT=prod
          ENVIRONMENT=prod
          IMAGE_TAG=${{ github.ref_name }}
          RELEASE_NAME=prod
          TRUSTED_HOST=$(echo ${{ vars.DOMAIN }} | sed 's/\./\\\\\\\\./g')

          echo "trusted_host=${TRUSTED_HOST}" >> $GITHUB_OUTPUT
          echo "context=${CONTEXT}" >> $GITHUB_OUTPUT
          echo "environment=${ENVIRONMENT}" >> $GITHUB_OUTPUT
          echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT
          echo "release_name=${RELEASE_NAME}" >> $GITHUB_OUTPUT
          echo "namespace=${CONTEXT}-${PROJECT}" >> $GITHUB_OUTPUT

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: 'read'
      id-token: 'write'
      pull-requests: 'write'
    environment:
      name: ${{ needs.meta.outputs.environment }}
    needs: ["meta"]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: GKE Auth
        uses: 'google-github-actions/auth@v2'
        with:
          project_id: '${{ secrets.project-id }}'
          workload_identity_provider: '${{ secrets.workload-identity-provider }}'

      - name: Setup gcloud
        uses: google-github-actions/setup-gcloud@v1
        with:
          project_id: ${{ secrets.project-id }}

      - name: Connect cluster
        run: |
          gcloud components install gke-gcloud-auth-plugin
          gcloud auth login --cred-file=$CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE
          gcloud container clusters get-credentials ${{ vars.CLUSTER_NAME }} --region europe-west1 --project ${{ secrets.project-id }}
          kubectl config view

      # https://github.com/helm/helm/issues/8036
      - name: Build helm dependencies
        run: |
          set -o pipefail
          # add all repos
          if [ -f "./helm/chart/Chart.lock" ]; then
            yq --indent 0 '.dependencies | map(["helm", "repo", "add", .name, .repository] | join(" ")) | .[]' "./helm/chart/Chart.lock"  | sh --;
          fi
          helm dependency build ./helm/chart

      - name: Deploy on namespace
        id: deploy
        shell: bash
        run: |
          set -o pipefail
          if ! helm upgrade --install ${{ needs.meta.outputs.release_name }} ./helm/chart \
            --atomic \
            --debug \
            --namespace ${{ needs.meta.outputs.namespace }} \
            --set=php.image.tag=${{ needs.meta.outputs.image_tag }} \
            --set=caddy.image.tag=${{ needs.meta.outputs.image_tag }} \
            --set=ingress.hosts[0].host=${{ vars.DOMAIN }} \
            --set=ingress.tls[0].secretName=${{ needs.meta.outputs.release_name }}-tls \
            --set=ingress.tls[0].hosts[0]=${{ vars.DOMAIN }} \
            --set=postgresql.url="${{ secrets.database-url }}" \
            --set=postgresql.enabled='${{ github.event_name == 'pull_request' }}' \
            --set=payum.apikey="${{ secrets.payum-apikey }}" \
            --set=mailer.dsn="${{ secrets.mailer-dsn }}" \
            --set=sms.dsn="${{ secrets.sms-dsn }}" \
            --set=php.storage.bucket="${{ vars.STORAGE_BUCKET }}" \
            --set=php.storage.endpoint="https://storage.googleapis.com" \
            --set=php.storage.region="eu-west-1" \
            --set=php.storage.usePathStyleEndpoint=true \
            --set=php.storage.key="${{ secrets.storage-key }}" \
            --set=php.storage.secret="${{ secrets.storage-secret-key }}" \
            --set=php.trustedHosts[2]=${{ needs.meta.outputs.trusted_host }} \
            --values ./helm/chart/values-${{ needs.meta.outputs.context }}.yml \
            | sed --unbuffered '/USER-SUPPLIED VALUES/,$d' ; then
                echo "Deployment has failed!"
                echo "Here are the last events to help diagnose the problem:"
                kubectl get events --namespace ${{ needs.meta.outputs.namespace }} --sort-by .metadata.creationTimestamp
                exit 1
          fi

      - name: Output deployment URL
        uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        env:
          URL: ${{ needs.meta.outputs.url }}
        with:
          script: |
            const { URL } = process.env
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `Chart has been deployed with this url:\n\`\`\`\n${URL}\n\`\`\``
            })
