name: PR Helm Chart

on:
  pull_request:
    paths:
      - charts/skillhub/**
      - .github/workflows/pr-helm-chart.yml
      - .github/workflows/publish-chart.yml
    types:
      - opened
      - synchronize
      - reopened
      - ready_for_review
  workflow_dispatch:

concurrency:
  group: pr-helm-chart-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  lint:
    name: Lint Chart
    if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: charts/skillhub

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Set up Helm
        uses: azure/setup-helm@v4
        with:
          version: v3.19.0

      - name: Build dependencies
        run: helm dependency build .

      - name: Lint chart
        run: helm lint --strict . -f tests/test-values.yaml

      - name: Validate configuration contracts
        run: bash tests/configuration-contracts.sh

      - name: Validate chart metadata
        run: |
          CHART_VERSION=$(helm show chart . | grep '^version:' | awk '{print $2}')
          APP_VERSION=$(helm show chart . | grep '^appVersion:' | awk '{print $2}')
          echo "Chart version: $CHART_VERSION"
          echo "App version: $APP_VERSION"
          if [ -z "$CHART_VERSION" ]; then
            echo "ERROR: Chart version is empty"
            exit 1
          fi

  template:
    name: Template Validation
    if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: charts/skillhub

    strategy:
      fail-fast: false
      matrix:
        scenario:
          - name: bitnami-default
            description: Bitnami 默认配置
            args: ""
          - name: external-db-redis
            description: 外部 PostgreSQL + Redis
            args: >-
              --set postgresql.enabled=false
              --set redis.enabled=false
              --set externalDatabase.host=postgres.example.com
              --set externalDatabase.password=secret
              --set externalRedis.host=redis.example.com
              --set externalRedis.password=secret
          - name: postgresql-replication
            description: PostgreSQL 主从 + Redis 主从
            args: >-
              --set postgresql.architecture=replication
              --set redis.architecture=replication
          - name: redis-sentinel
            description: Redis 哨兵模式
            args: >-
              --set redis.architecture=replication
              --set redis.sentinel.enabled=true
          - name: external-redis-cluster
            description: 外部 Redis Cluster
            args: >-
              --set redis.enabled=false
              --set externalRedis.cluster.enabled=true
              --set-json 'externalRedis.cluster.nodes=["redis-0.example.com:6379","redis-1.example.com:6379","redis-2.example.com:6379"]'
          - name: ingress-tls-certmanager
            description: Ingress + TLS + cert-manager
            args: >-
              --set ingress.enabled=true
              --set-json 'ingress.hosts=[{"host":"skills.example.com","paths":[{"path":"/","pathType":"Prefix"}]}]'
              --set-json 'ingress.tls=[{"hosts":["skills.example.com"],"secretName":"skills-tls"}]'
              --set ingress.certManager.enabled=true
          - name: s3-storage
            description: S3 存储
            args: >-
              --set s3.enabled=true
              --set s3.bucket=test-bucket
              --set s3.endpoint=https://s3.amazonaws.com
              --set s3.region=us-east-1
          - name: external-secret
            description: 外部 Secret
            args: >-
              --set existingSecret=my-custom-secret
          - name: scanner-disabled
            description: 禁用 Scanner
            args: >-
              --set scanner.enabled=false
          - name: hpa-pdb
            description: HPA + PDB
            args: >-
              --set server.autoscaling.enabled=true
              --set web.autoscaling.enabled=true
              --set scanner.autoscaling.enabled=true
              --set server.storage.accessMode=ReadWriteMany
              --set server.podDisruptionBudget.enabled=true
              --set web.podDisruptionBudget.enabled=true
              --set scanner.podDisruptionBudget.enabled=true

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Set up Helm
        uses: azure/setup-helm@v4
        with:
          version: v3.19.0

      - name: Build dependencies
        run: helm dependency build .

      - name: Render template - ${{ matrix.scenario.name }}
        run: |
          echo "## ${{ matrix.scenario.description }}"
          helm template test-release . -f tests/test-values.yaml ${{ matrix.scenario.args }} > rendered.yaml
          echo "✅ Template rendered successfully"

      - name: Validate resources
        run: |
          RESOURCES=$(grep -c '^kind:' rendered.yaml || true)
          echo "Rendered $RESOURCES resources for ${{ matrix.scenario.name }}"
          if [ "$RESOURCES" -eq 0 ]; then
            echo "ERROR: No resources rendered for ${{ matrix.scenario.name }}"
            exit 1
          fi

      - name: Validate default dependency wiring
        if: ${{ matrix.scenario.name == 'bitnami-default' }}
        run: |
          helm template test-release . -f tests/test-values.yaml --show-only templates/server-deployment.yaml > server.yaml
          grep -Fq 'value: "test-release-postgresql"' server.yaml
          grep -Fq 'value: "test-release-redis-master"' server.yaml
          grep -Fq 'name: test-release-postgresql' server.yaml
          grep -Fq 'name: test-release-redis' server.yaml
          grep -Fq 'key: password' server.yaml
          grep -Fq 'key: redis-password' server.yaml
          if grep -Fq 'test-release-skillhub-postgresql' server.yaml; then
            echo 'ERROR: Server references a non-existent PostgreSQL service'
            exit 1
          fi
          if grep -Fq 'test-release-skillhub-redis' server.yaml; then
            echo 'ERROR: Server references a non-existent Redis service'
            exit 1
          fi

      - name: Schema validation (kubeconform)
        uses: docker://ghcr.io/yannh/kubeconform@sha256:faffaf43f95aa6425306e1ab8d6fcad72acb9049158f38e574c085ea1ec0f64e # v0.8.0
        with:
          entrypoint: '/kubeconform'
          args: "-strict -summary -output text -schema-location default -schema-location https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json charts/skillhub/rendered.yaml"

  install-upgrade:
    name: Install and Upgrade Smoke (${{ matrix.scenario }})
    if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        scenario:
          - default
          - sentinel
          - s3
          - ingress-tls

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Set up Helm
        uses: azure/setup-helm@v4
        with:
          version: v3.19.0

      - name: Create Kubernetes cluster
        uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
        with:
          cluster_name: skillhub-helm-smoke
          wait: 120s

      - name: Run install and upgrade smoke
        env:
          HELM_SMOKE_SCENARIO: ${{ matrix.scenario }}
        run: bash charts/skillhub/tests/install-upgrade-smoke.sh
