# CI workflow for gpumod
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  PYTHON_VERSION: "3.12"
  UV_VERSION: "0.9.14"
  TRIVY_VERSION: "0.58.0"
  NO_COLOR: "1"  # Disable Rich ANSI codes in CLI tests

jobs:
  test:
    name: Test
    runs-on: self-hosted
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Python
        uses: https://github.com/actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Setup uv
        run: |
          export PATH="$HOME/.local/bin:$PATH"
          INSTALLED_VERSION=""
          if command -v uv &> /dev/null; then
            INSTALLED_VERSION=$(uv --version 2>/dev/null | grep -oP '\d+\.\d+\.\d+' || echo "")
          fi
          if [ "$INSTALLED_VERSION" != "${{ env.UV_VERSION }}" ]; then
            echo "Installing uv ${{ env.UV_VERSION }} (current: ${INSTALLED_VERSION:-none})"
            curl -LsSf https://astral.sh/uv/install.sh | sh
          else
            echo "uv ${{ env.UV_VERSION }} already installed"
          fi
          echo "$HOME/.local/bin" >> $GITHUB_PATH
          uv --version          

      - name: Install dependencies
        run: uv sync --group dev --python ${{ env.PYTHON_VERSION }}

      - name: Lint with Ruff
        run: |
          uv run ruff check src/ tests/
          uv run ruff format --check src/ tests/          

      - name: Type check with MyPy
        run: uv run mypy src/ --strict

      - name: Run tests
        timeout-minutes: 10
        run: |
          uv run pytest tests/ -v --tb=short \
            --timeout=60 \
            --cov=src/gpumod --cov-report=term-missing \
            --cov-fail-under=80 \
            -m "not gpu_required and not docker_required"          

  security:
    name: Security Scan (Trivy)
    needs: test
    runs-on: self-hosted
    steps:
      - name: Check available RAM
        run: |
          AVAIL_MB=$(awk '/MemAvailable/ {printf "%d", $2/1024}' /proc/meminfo)
          echo "Available RAM: ${AVAIL_MB} MB"
          if [ "$AVAIL_MB" -lt 1024 ]; then
            echo "::warning::Skipping security scan — only ${AVAIL_MB} MB RAM available (need 1024 MB)"
            echo "SKIP_SECURITY=true" >> $GITHUB_ENV
          fi

      - name: Checkout
        if: env.SKIP_SECURITY != 'true'
        uses: actions/checkout@v4

      - name: Install Trivy
        if: env.SKIP_SECURITY != 'true'
        run: |
          mkdir -p $HOME/.local/bin
          export PATH="$HOME/.local/bin:$PATH"
          if ! command -v trivy &> /dev/null || [ "$(trivy --version 2>/dev/null | grep -oP '\d+\.\d+\.\d+' | head -1)" != "${{ env.TRIVY_VERSION }}" ]; then
            echo "Installing Trivy ${{ env.TRIVY_VERSION }}..."
            curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b $HOME/.local/bin v${{ env.TRIVY_VERSION }}
          fi
          echo "$HOME/.local/bin" >> $GITHUB_PATH
          trivy --version          

      - name: Scan for vulnerabilities
        if: env.SKIP_SECURITY != 'true'
        run: |
          trivy fs . \
            --scanners vuln \
            --severity CRITICAL,HIGH \
            --ignore-unfixed \
            --exit-code 1 \
            --format table          

      - name: Scan for secrets
        if: env.SKIP_SECURITY != 'true'
        run: |
          trivy fs . \
            --scanners secret \
            --severity CRITICAL,HIGH \
            --exit-code 1 \
            --format table          

      - name: Scan for misconfigurations
        if: env.SKIP_SECURITY != 'true'
        run: |
          trivy config . \
            --severity CRITICAL,HIGH \
            --skip-policy-update \
            --exit-code 0 \
            --format table
        continue-on-error: true
