name: ci
on:
  - push
  - pull_request
env:
  golang-version: '1.18'
  kind-version: 'v0.14.0'
jobs:
  generate:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macos-latest
          - ubuntu-latest
    name: Generate
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - run: make --always-make generate validate && git diff --exit-code
  check-docs:
    runs-on: ubuntu-latest
    name: Check Documentation formatting and links
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - run: make check-docs
  lint:
    runs-on: ubuntu-latest
    name: Jsonnet linter
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - run: make --always-make lint
  fmt:
    runs-on: ubuntu-latest
    name: Jsonnet formatter
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - run: make --always-make fmt && git diff --exit-code
  unit-tests:
    runs-on: ubuntu-latest
    name: Unit tests
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - run: make --always-make test
  security-audit:
    runs-on: ubuntu-latest
    name: Run security analysis on manifests
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - run: make --always-make kubescape
  e2e-tests:
    name: E2E tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        kind-image:
          - 'kindest/node:v1.24.1'
          - 'kindest/node:v1.23.6'
    steps:
    - uses: actions/checkout@v3
      with:
        persist-credentials: false
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ env.golang-version }}
    - name: Start KinD
      uses: engineerd/setup-kind@v0.5.0
      with:
        version: ${{ env.kind-version }}
        image: ${{ matrix.kind-image }}
        wait: 10s # Without default CNI, control-plane doesn't get ready until Cilium is installed
        config: .github/workflows/kind/config.yml
    - name: Setup Helm
      uses: azure/setup-helm@v3.1
    - name: Install Cilium
      run: |
        helm repo add cilium https://helm.cilium.io/
        helm install cilium cilium/cilium --version 1.9.13 \
        --namespace kube-system \
        --set nodeinit.enabled=true \
        --set kubeProxyReplacement=partial \
        --set hostServices.enabled=false \
        --set externalIPs.enabled=true \
        --set nodePort.enabled=true \
        --set hostPort.enabled=true \
        --set bpf.masquerade=false \
        --set image.pullPolicy=IfNotPresent \
        --set ipam.mode=kubernetes \
        --set operator.replicas=1
    - name: Wait for cluster to finish bootstraping
      run: kubectl wait --for=condition=Ready pods --all --all-namespaces --timeout=300s
    - name: Create kube-prometheus stack
      run: |
        kubectl create -f manifests/setup
        until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
        kubectl create -f manifests/
    - name: Run tests
      run: |
        export KUBECONFIG="${HOME}/.kube/config"
        make test-e2e

  # Added to summarize the matrix and allow easy branch protection rules setup
  e2e-tests-result:
    name: End-to-End Test Results
    if: always()
    needs:
      - e2e-tests
    runs-on: ubuntu-latest
    steps:
      - name: Mark the job as a success
        if: needs.e2e-tests.result == 'success'
        run: exit 0
      - name: Mark the job as a failure
        if: needs.e2e-tests.result != 'success'
        run: exit 1
