# Coordinator Pipeline - Mosaic Stack
# Quality gates, build, and Docker publish for mosaic-coordinator (Python)
#
# Triggers on: apps/coordinator/**
# Security chain: bandit + pip-audit + Trivy container scan

when:
  - event: [push, pull_request, manual]
    path:
      include:
        - "apps/coordinator/**"
        - ".woodpecker/coordinator.yml"

variables:
  - &python_image "python:3.11-slim"
  - &activate_venv |
    cd apps/coordinator
    . venv/bin/activate
  - &kaniko_setup |
    mkdir -p /kaniko/.docker
    echo "{\"auths\":{\"git.mosaicstack.dev\":{\"username\":\"$GITEA_USER\",\"password\":\"$GITEA_TOKEN\"}}}" > /kaniko/.docker/config.json

steps:
  # === Quality Gates ===

  install:
    image: *python_image
    commands:
      - cd apps/coordinator
      - python -m venv venv
      - . venv/bin/activate
      - pip install --no-cache-dir --upgrade "pip>=25.3"
      - pip install --no-cache-dir --extra-index-url https://git.mosaicstack.dev/api/packages/mosaic/pypi/simple/ -e ".[dev]"
      - pip install --no-cache-dir bandit pip-audit

  ruff-check:
    image: *python_image
    commands:
      - *activate_venv
      - ruff check src/ tests/
    depends_on:
      - install

  mypy:
    image: *python_image
    commands:
      - *activate_venv
      - mypy src/
    depends_on:
      - install

  security-bandit:
    image: *python_image
    commands:
      - *activate_venv
      - bandit -r src/ -c bandit.yaml -f screen
    depends_on:
      - install

  security-pip-audit:
    image: *python_image
    commands:
      - *activate_venv
      - pip-audit
    depends_on:
      - install

  test:
    image: *python_image
    commands:
      - *activate_venv
      - pytest
    depends_on:
      - install

  # === Docker Build & Push ===

  docker-build-coordinator:
    image: gcr.io/kaniko-project/executor:debug
    environment:
      GITEA_USER:
        from_secret: gitea_username
      GITEA_TOKEN:
        from_secret: gitea_token
      CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
      CI_COMMIT_TAG: ${CI_COMMIT_TAG}
    commands:
      - *kaniko_setup
      - |
        DESTINATIONS=""
        if [ -n "$CI_COMMIT_TAG" ]; then
          DESTINATIONS="--destination git.mosaicstack.dev/mosaic/stack-coordinator:$CI_COMMIT_TAG"
        elif [ "$CI_COMMIT_BRANCH" = "main" ]; then
          DESTINATIONS="--destination git.mosaicstack.dev/mosaic/stack-coordinator:latest"
        elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then
          DESTINATIONS="--destination git.mosaicstack.dev/mosaic/stack-coordinator:dev"
        fi
        /kaniko/executor --context apps/coordinator --dockerfile apps/coordinator/Dockerfile --snapshot-mode=redo $DESTINATIONS
    when:
      - branch: [main, develop]
        event: [push, manual, tag]
    depends_on:
      - ruff-check
      - mypy
      - security-bandit
      - security-pip-audit
      - test

  # === Container Security Scan ===

  security-trivy-coordinator:
    image: aquasec/trivy:latest
    environment:
      GITEA_USER:
        from_secret: gitea_username
      GITEA_TOKEN:
        from_secret: gitea_token
      CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
      CI_COMMIT_TAG: ${CI_COMMIT_TAG}
    commands:
      - |
        if [ -n "$$CI_COMMIT_TAG" ]; then
          SCAN_TAG="$$CI_COMMIT_TAG"
        elif [ "$$CI_COMMIT_BRANCH" = "main" ]; then
          SCAN_TAG="latest"
        else
          SCAN_TAG="dev"
        fi
        mkdir -p ~/.docker
        echo "{\"auths\":{\"git.mosaicstack.dev\":{\"username\":\"$$GITEA_USER\",\"password\":\"$$GITEA_TOKEN\"}}}" > ~/.docker/config.json
        trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed \
          --ignorefile .trivyignore \
          git.mosaicstack.dev/mosaic/stack-coordinator:$$SCAN_TAG
    when:
      - branch: [main, develop]
        event: [push, manual, tag]
    depends_on:
      - docker-build-coordinator

  # === Package Linking ===

  link-packages:
    image: alpine:3
    environment:
      GITEA_TOKEN:
        from_secret: gitea_token
    commands:
      - apk add --no-cache curl
      - sleep 10
      - |
        set -e
        link_package() {
          PKG="$$1"
          echo "Linking $$PKG..."
          for attempt in 1 2 3; do
            STATUS=$$(curl -s -o /tmp/link-response.txt -w "%{http_code}" -X POST \
              -H "Authorization: token $$GITEA_TOKEN" \
              "https://git.mosaicstack.dev/api/v1/packages/mosaic/container/$$PKG/-/link/stack")
            if [ "$$STATUS" = "201" ] || [ "$$STATUS" = "204" ]; then
              echo "  Linked $$PKG"
              return 0
            elif [ "$$STATUS" = "400" ]; then
              echo "  $$PKG already linked"
              return 0
            elif [ "$$STATUS" = "404" ] && [ $$attempt -lt 3 ]; then
              echo "  $$PKG not found yet, retrying in 5s (attempt $$attempt/3)..."
              sleep 5
            else
              echo "  FAILED: $$PKG status $$STATUS"
              cat /tmp/link-response.txt
              return 1
            fi
          done
        }
        link_package "stack-coordinator"
    when:
      - branch: [main, develop]
        event: [push, manual, tag]
    depends_on:
      - security-trivy-coordinator
