name: ci

on:
    push:
    workflow_dispatch:
      inputs:
        tag:
          description: 'Tag to deploy'
          required: false
          default: 'latest'

jobs:
    build:
        runs-on: ubuntu-latest

        strategy:
            matrix:
                node-version: [22.12.0]
                # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

        steps:
            - uses: actions/checkout@v3
            - name: Use Node.js ${{ matrix.node-version }}
              uses: actions/setup-node@v3
              with:
                  node-version: ${{ matrix.node-version }}
                  cache: "npm"
            - run: npm install
            - run: npm run build --if-present

    docker:
        needs: [build]
        runs-on: ubuntu-latest
        if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
        permissions:
          contents: read
          packages: write   # required to push to ghcr.io
          id-token: write   # optional for OIDC if you use it

        steps:
            - uses: actions/checkout@v3

            - name: Set up QEMU
              uses: docker/setup-qemu-action@v3

            - name: Set up Docker Buildx
              uses: docker/setup-buildx-action@v3

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

            - name: Prepare image tags
              run: |
                OWNER=$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')
                REPO=$(echo "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]')

                # Determine tag
                if [ "${GITHUB_REF_NAME}" = "main" ]; then
                  TAG="latest"
                else
                  TAG="dev"
                fi

                SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
                IMAGE_BASE="ghcr.io/${OWNER}/${REPO}"

                echo "IMAGE_LATEST=${IMAGE_BASE}:${TAG}" >> $GITHUB_ENV
                echo "IMAGE_SHA=${IMAGE_BASE}:sha-${SHORT_SHA}" >> $GITHUB_ENV

            - name: Build and push Docker image (with registry cache)
              uses: docker/build-push-action@v5
              with:
                context: .
                push: true
                platforms: linux/amd64,linux/arm64
                tags: |
                  ${{ env.IMAGE_LATEST }}
                  ${{ env.IMAGE_SHA }}
                cache-from: type=gha
                cache-to: type=gha,mode=max

    deploy:
        needs: [docker]
        runs-on: ubuntu-latest
        if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
        environment:
          name: ${{ github.ref_name == 'main' && 'production' || 'dev' }}
          url: https://${{ vars.KUBE_DOMAIN }}
        env:
          # Kubernetes Specific
          KUBE_NAMESPACE: ${{ vars.KUBE_NAMESPACE }}
          KUBE_DOMAIN: ${{ vars.KUBE_DOMAIN }}
          WORKER_NODE_LABEL: ${{ vars.WORKER_NODE_LABEL }}
          # Application Specific
          BACKEND_URL: ${{ vars.BACKEND_URL }}
          GH_USER: ${{ vars.GH_USER }}

        steps:
          - uses: actions/checkout@v4
          - uses: azure/setup-kubectl@v4

          - name: Set Up Kubeconfig
            uses: azure/k8s-set-context@v4
            with:
              kubeconfig: ${{ secrets.PORTFOLIO_KUBECONFIG }}

          - name: Prepare Image Tag
            run: |
              OWNER=$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')
              REPO=$(echo "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]')
              SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)

              IMAGE_BASE="ghcr.io/${OWNER}/${REPO}"
              IMAGE_TAG="sha-${SHORT_SHA}"

              echo "IMAGE_BASE=${IMAGE_BASE}" >> $GITHUB_ENV
              echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV

          - name: Apply Kubernetes Manifests - Configuration
            run: cat .k8s/config.yml | envsubst | kubectl apply -f -

          - name: Apply Kubernetes Manifests - Deployment
            run: |
                cat .k8s/deployment.yaml | envsubst | kubectl apply -f -
                cat .k8s/deployment.yaml | envsubst | kubectl rollout status deployment/frontend-deployment -n ${KUBE_NAMESPACE} --timeout=120s

          - name: Apply Kubernetes Manifests - Service
            run: cat .k8s/service.yaml | envsubst | kubectl apply -f -

          - name: Apply Kubernetes Manifests - Ingress
            run: cat .k8s/ingress.yaml | envsubst | kubectl apply -f -
