name: b-binary-build-and-e2e-tests
permissions: read-all
on:
  workflow_dispatch:
    inputs:
      COMPONENT_NAME:
        required: false
        type: string
        default: "kubescape"
      RELEASE:
        required: false
        type: string
        default: ""
      CLIENT:
        required: false
        type: string
        default: "test"
      GO_VERSION:
        required: false
        type: string
        default: "1.23"
      GO111MODULE:
        required: false
        type: string
        default: ""
      CGO_ENABLED:
        type: number
        default: 1
        required: false
      BINARY_TESTS:
        type: string
        required: false
        default: '[
          "ks_microservice_create_2_cronjob_mitre_and_nsa_proxy",
          "ks_microservice_triggering_with_cron_job",
          "ks_microservice_update_cronjob_schedule",
          "ks_microservice_delete_cronjob",
          "ks_microservice_create_2_cronjob_mitre_and_nsa",
          "ks_microservice_ns_creation",
          "ks_microservice_on_demand",
          "ks_microservice_mitre_framework_on_demand",
          "ks_microservice_nsa_and_mitre_framework_demand",
          "scan_nsa",
          "scan_mitre",
          "scan_with_exceptions",
          "scan_repository",
          "scan_local_file",
          "scan_local_glob_files",
          "scan_local_list_of_files",
          "scan_with_exception_to_backend",
          "scan_nsa_and_submit_to_backend",
          "scan_mitre_and_submit_to_backend",
          "scan_local_repository_and_submit_to_backend",
          "scan_repository_from_url_and_submit_to_backend",
          "scan_with_custom_framework",
          "scan_customer_configuration",
          "scan_compliance_score"
          ]'

  workflow_call:
    inputs:
      COMPONENT_NAME:
        required: true
        type: string
      RELEASE:
        required: true
        type: string
      CLIENT:
        required: true
        type: string
      GO_VERSION:
        type: string
        default: "1.23"
      GO111MODULE:
        required: true
        type: string
      CGO_ENABLED:
        type: number
        default: 1
      BINARY_TESTS:
        type: string
        default: '[ 
          "scan_nsa", 
          "scan_mitre", 
          "scan_with_exceptions", 
          "scan_repository", 
          "scan_local_file", 
          "scan_local_glob_files", 
          "scan_local_list_of_files", 
          "scan_nsa_and_submit_to_backend", 
          "scan_mitre_and_submit_to_backend", 
          "scan_local_repository_and_submit_to_backend", 
          "scan_repository_from_url_and_submit_to_backend", 
          "scan_with_custom_framework", 
          "scan_customer_configuration", 
          "scan_compliance_score", 
          "scan_custom_framework_scanning_file_scope_testing", 
          "scan_custom_framework_scanning_cluster_scope_testing", 
          "scan_custom_framework_scanning_cluster_and_file_scope_testing"
          ]'

jobs:
  wf-preparation:
    name: secret-validator
    runs-on: ubuntu-latest
    outputs:
      TEST_NAMES: ${{ steps.export_tests_to_env.outputs.TEST_NAMES }}
      is-secret-set: ${{ steps.check-secret-set.outputs.is-secret-set }}

    steps:
      - name: check if the necessary secrets are set in github secrets
        id: check-secret-set
        env:
          CUSTOMER: ${{ secrets.CUSTOMER }}
          USERNAME: ${{ secrets.USERNAME }}
          PASSWORD: ${{ secrets.PASSWORD }}
          CLIENT_ID: ${{ secrets.CLIENT_ID_PROD }}
          SECRET_KEY: ${{ secrets.SECRET_KEY_PROD }}
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: "echo \"is-secret-set=${{ env.CUSTOMER != '' && env.USERNAME != '' && env.PASSWORD != '' && env.CLIENT_ID != '' && env.SECRET_KEY != '' && env.REGISTRY_USERNAME != '' && env.REGISTRY_PASSWORD != '' }}\" >> $GITHUB_OUTPUT\n"

      - id: export_tests_to_env
        name: set test name
        run: |
          echo "TEST_NAMES=$input" >> $GITHUB_OUTPUT
        env:
          input: ${{ inputs.BINARY_TESTS }}

  check-secret:
    name: check if QUAYIO_REGISTRY_USERNAME & QUAYIO_REGISTRY_PASSWORD is set in github secrets
    runs-on: ubuntu-latest
    outputs:
      is-secret-set: ${{ steps.check-secret-set.outputs.is-secret-set }}
    steps:
      - name: check if QUAYIO_REGISTRY_USERNAME & QUAYIO_REGISTRY_PASSWORD is set in github secrets
        id: check-secret-set
        env:
          QUAYIO_REGISTRY_USERNAME: ${{ secrets.QUAYIO_REGISTRY_USERNAME }}
          QUAYIO_REGISTRY_PASSWORD: ${{ secrets.QUAYIO_REGISTRY_PASSWORD }}
        run: |
          echo "is-secret-set=${{ env.QUAYIO_REGISTRY_USERNAME != '' && env.QUAYIO_REGISTRY_PASSWORD != '' }}" >> $GITHUB_OUTPUT

  binary-build:
    name: Create cross-platform build
    needs: wf-preparation
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    runs-on: ubuntu-large
    steps:
      - name: (debug) Step 1 - Check disk space before checkout
        run: df -h

      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          submodules: recursive

      - name: (debug) Step 2 - Check disk space before installing Go
        run: df -h

      - uses: actions/setup-go@v4
        name: Installing go
        with:
          go-version: ${{ inputs.GO_VERSION }}
          cache: true

      - name: (debug) Step 3 - Check disk space before build
        run: df -h

      - name: Test core pkg
        run: ${{ env.DOCKER_CMD }} go test -v ./...
        if: startsWith(github.ref, 'refs/tags')

      - name: (debug) Step 4 - Check disk space before testing httphandler pkg
        run: df -h

      - name: Test httphandler pkg
        run: ${{ env.DOCKER_CMD }} sh -c 'cd httphandler && go test -v ./...'
        if: startsWith(github.ref, 'refs/tags')

      - name: (debug) Step 5 - Check disk space before setting up Syft
        run: df -h

      - uses: anchore/sbom-action/download-syft@v0.15.2
        name: Setup Syft

      - name: (debug) Step 6 - Check disk space before goreleaser
        run: df -h

      - uses: goreleaser/goreleaser-action@v5
        name: Build
        with:
          distribution: goreleaser
          version: latest
          args: release --clean --snapshot
        env:
          RELEASE: ${{ inputs.RELEASE }}
          CLIENT: ${{ inputs.CLIENT }}
          CGO_ENABLED: ${{ inputs.CGO_ENABLED }}

      - name: (debug) Step 7 - Check disk space before smoke testing
        run: df -h

      - name: Smoke Testing
        env:
          RELEASE: ${{ inputs.RELEASE }}
          KUBESCAPE_SKIP_UPDATE_CHECK: "true"
        run: ${{ env.DOCKER_CMD }} python3 smoke_testing/init.py ${PWD}/dist/kubescape-ubuntu-latest

      - name: (debug) Step 8 - Check disk space before golangci-lint
        run: df -h

      - name: golangci-lint
        continue-on-error: true
        uses: golangci/golangci-lint-action@v3
        with:
          version: latest
          args: --timeout 10m
          only-new-issues: true
          skip-pkg-cache: true
          skip-build-cache: true

      - name: (debug) Step 9 - Check disk space before uploading artifacts
        run: df -h

      - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # ratchet:actions/upload-artifact@v3.1.1
        name: Upload artifacts
        with:
          name: kubescape
          path: dist/kubescape*
          if-no-files-found: error

      - name: (debug) Step 10 - Check disk space after uploading artifacts
        run: df -h

  build-http-image:
    permissions:
      contents: write
      id-token: write
      packages: write
      pull-requests: read
    needs: [check-secret]
    uses: kubescape/workflows/.github/workflows/incluster-comp-pr-merged.yaml@main
    with:
      IMAGE_NAME: quay.io/${{ github.repository_owner }}/kubescape
      IMAGE_TAG: ${{ inputs.RELEASE }}
      COMPONENT_NAME: kubescape
      CGO_ENABLED: 0
      GO111MODULE: "on"
      BUILD_PLATFORM: linux/amd64,linux/arm64
      GO_VERSION: "1.23"
      REQUIRED_TESTS: '[
                "ks_microservice_create_2_cronjob_mitre_and_nsa_proxy", 
                "ks_microservice_triggering_with_cron_job",
                "ks_microservice_update_cronjob_schedule",
                "ks_microservice_delete_cronjob",
                "ks_microservice_create_2_cronjob_mitre_and_nsa",
                "ks_microservice_ns_creation",
                "ks_microservice_on_demand",
                "ks_microservice_mitre_framework_on_demand",
                "ks_microservice_nsa_and_mitre_framework_demand",
                "scan_nsa", 
                "scan_mitre", 
                "scan_with_exceptions", 
                "scan_repository", 
                "scan_local_file", 
                "scan_local_glob_files", 
                "scan_local_list_of_files", 
                "scan_with_exception_to_backend", 
                "scan_nsa_and_submit_to_backend", 
                "scan_mitre_and_submit_to_backend", 
                "scan_local_repository_and_submit_to_backend", 
                "scan_repository_from_url_and_submit_to_backend", 
                "scan_with_custom_framework", 
                "scan_customer_configuration", 
                "scan_compliance_score"
                ]'
      COSIGN: true
      HELM_E2E_TEST: true
      FORCE: true
    secrets: inherit

  run-tests:
    strategy:
      fail-fast: false
      matrix:
        TEST: ${{ fromJson(needs.wf-preparation.outputs.TEST_NAMES) }}
    needs: [wf-preparation, binary-build]
    if: ${{ (needs.wf-preparation.outputs.is-secret-set == 'true') && (always() && (contains(needs.*.result, 'success') || contains(needs.*.result, 'skipped')) && !(contains(needs.*.result, 'failure')) && !(contains(needs.*.result, 'cancelled'))) }}
    runs-on: ubuntu-latest # This cannot change
    steps:
      - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # ratchet:actions/download-artifact@v3.0.2
        id: download-artifact
        with:
          name: kubescape
          path: "~"

      - run: ls -laR

      - name: chmod +x
        run: chmod +x -R ${{steps.download-artifact.outputs.download-path}}/kubescape-ubuntu-latest

      - name: Checkout systests repo
        uses: actions/checkout@v4
        with:
          repository: armosec/system-tests
          path: .

      - uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # ratchet:actions/setup-python@v4
        with:
          python-version: '3.8.13'
          cache: 'pip'

      - name: create env
        run: ./create_env.sh

      - name: Generate uuid
        id: uuid
        run: |
          echo "RANDOM_UUID=$(uuidgen)" >> $GITHUB_OUTPUT

      - name: Create k8s Kind Cluster
        id: kind-cluster-install
        uses: helm/kind-action@v1.10.0
        with:
          cluster_name: ${{ steps.uuid.outputs.RANDOM_UUID }}

      - name: run-tests-on-local-built-kubescape
        env:
          CUSTOMER: ${{ secrets.CUSTOMER }}
          USERNAME: ${{ secrets.USERNAME }}
          PASSWORD: ${{ secrets.PASSWORD }}
          CLIENT_ID: ${{ secrets.CLIENT_ID_PROD }}
          SECRET_KEY: ${{ secrets.SECRET_KEY_PROD }}
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: |
          echo "Test history:"
          echo " ${{ matrix.TEST }} " >/tmp/testhistory
          cat /tmp/testhistory
          source systests_python_env/bin/activate

          python3 systest-cli.py             \
            -t ${{ matrix.TEST }}            \
            -b production                    \
            -c CyberArmorTests               \
            --duration 3                     \
            --logger DEBUG                   \
            --kwargs kubescape=${{steps.download-artifact.outputs.download-path}}/kubescape-ubuntu-latest

          deactivate

      - name: Test Report
        uses: mikepenz/action-junit-report@6e9933f4a97f4d2b99acef4d7b97924466037882 # ratchet:mikepenz/action-junit-report@v3.6.1
        if: always() # always run even if the previous step fails
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          report_paths: '**/results_xml_format/**.xml'
          commit: ${{github.event.workflow_run.head_sha}}
