name: Build and Publish Docker Images

on:
  push:
    branches: [ main, develop ]
    tags: [ 'v*' ]
  pull_request:
    branches: [ main ]

env:
  REGISTRY: docker.io
  IMAGE_NAME_DISCORD_BOT: uptime-kuma-discord-bot
  IMAGE_NAME_WEB_BACKEND: uptime-kuma-web-backend

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

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

    - name: Log in to Docker Hub
      if: github.event_name != 'pull_request'
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Extract metadata for Discord Bot
      id: meta-discord-bot
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=semver,pattern={{major}}
          type=raw,value=latest,enable={{is_default_branch}}

    - name: Extract metadata for Web Backend
      id: meta-web-backend
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=semver,pattern={{major}}
          type=raw,value=latest,enable={{is_default_branch}}

    - name: Build and push Discord Bot image
      uses: docker/build-push-action@v5
      with:
        context: ./Bot
        file: ./Bot/Dockerfile
        push: ${{ github.event_name != 'pull_request' }}
        tags: ${{ steps.meta-discord-bot.outputs.tags }}
        labels: ${{ steps.meta-discord-bot.outputs.labels }}
        platforms: linux/amd64,linux/arm64
        cache-from: type=gha
        cache-to: type=gha,mode=max

    - name: Build and push Web Backend image
      uses: docker/build-push-action@v5
      with:
        context: ./Web
        file: ./Web/Dockerfile
        push: ${{ github.event_name != 'pull_request' }}
        tags: ${{ steps.meta-web-backend.outputs.tags }}
        labels: ${{ steps.meta-web-backend.outputs.labels }}
        platforms: linux/amd64,linux/arm64
        cache-from: type=gha
        cache-to: type=gha,mode=max

    - name: Generate SBOM for Discord Bot
      if: github.event_name != 'pull_request'
      uses: anchore/sbom-action@v0
      with:
        image: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:${{ steps.meta-discord-bot.outputs.version }}
        format: spdx-json
        output-file: discord-bot-sbom.spdx.json

    - name: Generate SBOM for Web Backend
      if: github.event_name != 'pull_request'
      uses: anchore/sbom-action@v0
      with:
        image: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:${{ steps.meta-web-backend.outputs.version }}
        format: spdx-json
        output-file: web-backend-sbom.spdx.json

    - name: Upload SBOM artifacts
      if: github.event_name != 'pull_request'
      uses: actions/upload-artifact@v4
      with:
        name: sbom-artifacts
        path: |
          discord-bot-sbom.spdx.json
          web-backend-sbom.spdx.json
        retention-days: 30

  security-scan:
    runs-on: ubuntu-latest
    needs: build-and-push
    if: github.event_name != 'pull_request'
    permissions:
      contents: read
      security-events: write

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Run Trivy vulnerability scanner for Discord Bot
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest
        format: 'sarif'
        output: 'discord-bot-trivy-results.sarif'

    - name: Run Trivy vulnerability scanner for Web Backend
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest
        format: 'sarif'
        output: 'web-backend-trivy-results.sarif'

    - name: Upload Trivy scan results to GitHub Security tab
      uses: github/codeql-action/upload-sarif@v3
      with:
        sarif_file: |
          discord-bot-trivy-results.sarif
          web-backend-trivy-results.sarif

  notify:
    runs-on: ubuntu-latest
    needs: [build-and-push, security-scan]
    if: always() && github.event_name != 'pull_request'
    
    steps:
    - name: Notify on success
      if: needs.build-and-push.result == 'success' && needs.security-scan.result == 'success'
      run: |
        echo "✅ Docker images built and published successfully!"
        echo "Discord Bot: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest"
        echo "Web Backend: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest"

    - name: Notify on failure
      if: needs.build-and-push.result == 'failure' || needs.security-scan.result == 'failure'
      run: |
        echo "❌ Docker build or security scan failed!"
        exit 1
