name: CD - Build & Deploy

on:
  push:
    branches: [ main ]
    tags:
      - 'v*'

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    
    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
      image-version: ${{ steps.meta.outputs.version }}
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: Log in to Container Registry
      uses: docker/login-action@v2
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=sha,prefix={{branch}}-
          type=raw,value=latest,enable={{is_default_branch}}
    
    - name: Build and push Docker image
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
        cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
        platforms: linux/amd64
    
    - name: Image digest
      run: echo "Image pushed with digest ${{ steps.build.outputs.digest }}"

  package-helm:
    runs-on: ubuntu-latest
    needs: build-and-push
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    
    - name: Install Helm
      uses: azure/setup-helm@v3
      with:
        version: 'latest'
    
    - name: Package Helm chart
      run: |
        helm package helm/peikarband --destination .
        helm repo index . --url https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}
    
    - name: Upload Helm chart artifact
      uses: actions/upload-artifact@v3
      with:
        name: helm-chart
        path: |
          *.tgz
          index.yaml

  deploy-staging:
    runs-on: ubuntu-latest
    needs: [build-and-push, package-helm]
    if: github.ref == 'refs/heads/main'
    environment:
      name: staging
      url: https://staging.peikarband.ir
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    
    - name: Install kubectl
      uses: azure/setup-kubectl@v3
    
    - name: Install Helm
      uses: azure/setup-helm@v3
    
    - name: Configure kubectl
      run: |
        echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > kubeconfig
        export KUBECONFIG=kubeconfig
    
    - name: Deploy to Staging
      run: |
        export KUBECONFIG=kubeconfig
        helm upgrade --install peikarband-staging ./helm/peikarband \
          --namespace staging \
          --create-namespace \
          --set image.tag=${{ needs.build-and-push.outputs.image-version }} \
          --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \
          --set ingress.hosts[0].host=staging.peikarband.ir \
          --wait \
          --timeout 5m

  deploy-production:
    runs-on: ubuntu-latest
    needs: [build-and-push, package-helm]
    if: startsWith(github.ref, 'refs/tags/v')
    environment:
      name: production
      url: https://peikarband.ir
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    
    - name: Install kubectl
      uses: azure/setup-kubectl@v3
    
    - name: Install Helm
      uses: azure/setup-helm@v3
    
    - name: Configure kubectl
      run: |
        echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 -d > kubeconfig
        export KUBECONFIG=kubeconfig
    
    - name: Deploy to Production
      run: |
        export KUBECONFIG=kubeconfig
        helm upgrade --install peikarband-prod ./helm/peikarband \
          --namespace production \
          --create-namespace \
          --set image.tag=${{ needs.build-and-push.outputs.image-version }} \
          --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \
          --set replicaCount=3 \
          --set autoscaling.enabled=true \
          --values helm/peikarband/values-production.yaml \
          --wait \
          --timeout 10m
    
    - name: Verify deployment
      run: |
        export KUBECONFIG=kubeconfig
        kubectl rollout status deployment/peikarband-prod -n production
        kubectl get pods -n production

  release:
    runs-on: ubuntu-latest
    needs: [build-and-push, package-helm, deploy-production]
    if: startsWith(github.ref, 'refs/tags/v')
    permissions:
      contents: write
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    
    - name: Download Helm chart
      uses: actions/download-artifact@v3
      with:
        name: helm-chart
    
    - name: Create Release
      uses: softprops/action-gh-release@v1
      with:
        files: |
          *.tgz
          index.yaml
        generate_release_notes: true
        draft: false
        prerelease: false

