name: CI

on:
  push:
    branches: [main, 'feature/**', 'fix/**', 'feat/**']
    tags-ignore:
      - 'v*'
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    if: github.event_name != 'delete'
    container:
      image: gitea.siegeln.net/cameleer/cameleer-build:1
      credentials:
        username: cameleer
        password: ${{ secrets.REGISTRY_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - name: Cache Maven dependencies
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: ${{ runner.os }}-maven-

      - name: Build SaaS frontend
        run: |
          cd ui
          echo "//gitea.siegeln.net/api/packages/cameleer/npm/:_authToken=${REGISTRY_TOKEN}" >> .npmrc
          npm ci
          npm run build
          cp -r dist/ ../src/main/resources/static/
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

      - name: Build and Test (unit tests only)
        run: >-
          mvn clean verify -B
          -Dsurefire.excludes="**/AuthControllerTest.java,**/TenantControllerTest.java,**/LicenseControllerTest.java,**/AuditRepositoryTest.java,**/CameleerSaasApplicationTest.java,**/EnvironmentControllerTest.java,**/AppControllerTest.java,**/DeploymentControllerTest.java,**/AgentStatusControllerTest.java,**/VendorTenantControllerTest.java,**/TenantPortalControllerTest.java"

      - name: Build sign-in UI
        run: |
          cd ui/sign-in
          echo "//gitea.siegeln.net/api/packages/cameleer/npm/:_authToken=${REGISTRY_TOKEN}" >> .npmrc
          npm ci
          npm run build
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

  docker:
    needs: build
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    container:
      image: gitea.siegeln.net/cameleer/cameleer-docker-builder:1
      credentials:
        username: cameleer
        password: ${{ secrets.REGISTRY_TOKEN }}
    steps:
      - name: Checkout
        run: |
          git clone --depth=1 --branch=${GITHUB_REF_NAME} https://cameleer:${REGISTRY_TOKEN}@gitea.siegeln.net/${GITHUB_REPOSITORY}.git .
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

      - name: Login to registry
        run: echo "$REGISTRY_TOKEN" | docker login gitea.siegeln.net -u cameleer --password-stdin
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

      - name: Compute image tags
        run: |
          sanitize_branch() {
            echo "$1" | sed -E 's#^(feature|fix|feat|hotfix)/##' \
              | tr '[:upper:]' '[:lower:]' \
              | sed 's/[^a-z0-9-]/-/g' \
              | sed 's/--*/-/g; s/^-//; s/-$//' \
              | cut -c1-20 \
              | sed 's/-$//'
          }
          if [ "$GITHUB_REF_NAME" = "main" ]; then
            echo "IMAGE_TAGS=latest" >> "$GITHUB_ENV"
          else
            SLUG=$(sanitize_branch "$GITHUB_REF_NAME")
            echo "IMAGE_TAGS=branch-$SLUG" >> "$GITHUB_ENV"
          fi

      - name: Set up QEMU for cross-platform builds
        run: docker run --rm --privileged gitea.siegeln.net/cameleer/binfmt:1 --install all

      - name: Build and push SaaS image
        run: |
          docker buildx create --use --name cibuilder
          TAGS="-t gitea.siegeln.net/cameleer/cameleer-saas:${{ github.sha }}"
          for TAG in $IMAGE_TAGS; do
            TAGS="$TAGS -t gitea.siegeln.net/cameleer/cameleer-saas:$TAG"
          done
          docker buildx build --platform linux/amd64 \
            --build-arg REGISTRY_TOKEN="$REGISTRY_TOKEN" \
            $TAGS \
            --cache-from type=registry,ref=gitea.siegeln.net/cameleer/cameleer-saas:buildcache \
            --cache-to type=registry,ref=gitea.siegeln.net/cameleer/cameleer-saas:buildcache,mode=max \
            --provenance=false \
            --push .
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

      - name: Build and push runtime base image
        run: |
          AGENT_VERSION=$(curl -sf "https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer/cameleer-agent/1.0-SNAPSHOT/maven-metadata.xml" \
            | sed -n 's/.*<value>\([^<]*\)<\/value>.*/\1/p' | tail -1)
          echo "Agent version: $AGENT_VERSION"
          curl -sf -o docker/runtime-base/agent.jar \
            "https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer/cameleer-agent/1.0-SNAPSHOT/cameleer-agent-${AGENT_VERSION}-shaded.jar"
          APPENDER_VERSION=$(curl -sf "https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer/cameleer-log-appender/1.0-SNAPSHOT/maven-metadata.xml" \
            | sed -n 's/.*<value>\([^<]*\)<\/value>.*/\1/p' | tail -1)
          echo "Log appender version: $APPENDER_VERSION"
          curl -sf -o docker/runtime-base/cameleer-log-appender.jar \
            "https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer/cameleer-log-appender/1.0-SNAPSHOT/cameleer-log-appender-${APPENDER_VERSION}.jar"
          ls -la docker/runtime-base/agent.jar docker/runtime-base/cameleer-log-appender.jar
          TAGS="-t gitea.siegeln.net/cameleer/cameleer-runtime-base:${{ github.sha }}"
          for TAG in $IMAGE_TAGS; do
            TAGS="$TAGS -t gitea.siegeln.net/cameleer/cameleer-runtime-base:$TAG"
          done
          docker buildx build --platform linux/amd64 \
            $TAGS \
            --provenance=false \
            --push docker/runtime-base/

      - name: Build and push Logto image
        run: |
          TAGS="-t gitea.siegeln.net/cameleer/cameleer-logto:${{ github.sha }}"
          for TAG in $IMAGE_TAGS; do
            TAGS="$TAGS -t gitea.siegeln.net/cameleer/cameleer-logto:$TAG"
          done
          docker buildx build --platform linux/amd64 \
            --build-arg REGISTRY_TOKEN="$REGISTRY_TOKEN" \
            -f ui/sign-in/Dockerfile \
            $TAGS \
            --cache-from type=registry,ref=gitea.siegeln.net/cameleer/cameleer-logto:buildcache \
            --cache-to type=registry,ref=gitea.siegeln.net/cameleer/cameleer-logto:buildcache,mode=max \
            --provenance=false \
            --push .
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

      - name: Build and push PostgreSQL image
        run: |
          TAGS="-t gitea.siegeln.net/cameleer/cameleer-postgres:${{ github.sha }}"
          for TAG in $IMAGE_TAGS; do
            TAGS="$TAGS -t gitea.siegeln.net/cameleer/cameleer-postgres:$TAG"
          done
          docker buildx build --platform linux/amd64 \
            $TAGS \
            --provenance=false \
            --push docker/cameleer-postgres/

      - name: Build and push ClickHouse image
        run: |
          TAGS="-t gitea.siegeln.net/cameleer/cameleer-clickhouse:${{ github.sha }}"
          for TAG in $IMAGE_TAGS; do
            TAGS="$TAGS -t gitea.siegeln.net/cameleer/cameleer-clickhouse:$TAG"
          done
          docker buildx build --platform linux/amd64 \
            $TAGS \
            --provenance=false \
            --push docker/cameleer-clickhouse/

      - name: Build and push Traefik image
        run: |
          TAGS="-t gitea.siegeln.net/cameleer/cameleer-traefik:${{ github.sha }}"
          for TAG in $IMAGE_TAGS; do
            TAGS="$TAGS -t gitea.siegeln.net/cameleer/cameleer-traefik:$TAG"
          done
          docker buildx build --platform linux/amd64 \
            $TAGS \
            --provenance=false \
            --push docker/cameleer-traefik/
