name: Diff
concurrency:
  group: ${{ github.head_ref || github.sha }}
  cancel-in-progress: true

on:
  push:
    branches:
      - master
  workflow_dispatch:
  pull_request:
    paths-ignore:
      - "docs/**"
      - "**/*.md"
      - ".clang-format"
      - "CODEOWNERS"

jobs:
  community_build:
    name: "Community build"
    runs-on: [self-hosted, Linux, X64, Diff]
    env:
      THREADS: 24
      MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
      MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}

    steps:
      - name: Set up repository
        uses: actions/checkout@v3
        with:
          # Number of commits to fetch. `0` indicates all history for all
          # branches and tags. (default: 1)
          fetch-depth: 0

      - name: Build community binaries
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Initialize dependencies.
          ./init

          # Build community binaries.
          cd build
          cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
          make -j$THREADS

      - name: Run unit tests
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run unit tests.
          cd build
          ctest -R memgraph__unit --output-on-failure -j$THREADS

  code_analysis:
    name: "Code analysis"
    runs-on: [self-hosted, Linux, X64, Diff]
    env:
      THREADS: 24
      MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
      MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}

    steps:
      - name: Set up repository
        uses: actions/checkout@v3
        with:
          # Number of commits to fetch. `0` indicates all history for all
          # branches and tags. (default: 1)
          fetch-depth: 0

        # This is also needed if we want do to comparison against other branches
        # See https://github.community/t/checkout-code-fails-when-it-runs-lerna-run-test-since-master/17920
      - name: Fetch all history for all tags and branches
        run: git fetch

      - name: Initialize deps
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate
          # Initialize dependencies.
          ./init

      - name: Set base branch
        if: ${{ github.event_name == 'pull_request' }}
        run: |
          echo "BASE_BRANCH=origin/${{ github.base_ref }}" >> $GITHUB_ENV

      - name: Set base branch # if we manually dispatch or push to master
        if: ${{ github.event_name != 'pull_request' }}
        run: |
          echo "BASE_BRANCH=origin/master" >> $GITHUB_ENV

      - name: Python code analysis
        run: |
          CHANGED_FILES=$(git diff -U0 ${{ env.BASE_BRANCH }}... --name-only)
          for file in ${CHANGED_FILES}; do
            echo ${file}
            if [[ ${file} == *.py ]]; then
              python3 -m black --check --diff ${file}
              python3 -m isort --check-only --profile "black" --diff ${file}
            fi
          done

      - name: Build combined ASAN, UBSAN and coverage binaries
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          cd build
          cmake -DTEST_COVERAGE=ON -DASAN=ON -DUBSAN=ON ..
          make -j$THREADS memgraph__unit

      - name: Run unit tests
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run unit tests. It is restricted to 2 threads intentionally, because higher concurrency makes the timing related tests unstable.
          cd build
          LSAN_OPTIONS=suppressions=$PWD/../tools/lsan.supp UBSAN_OPTIONS=halt_on_error=1 ctest -R memgraph__unit --output-on-failure -j2

      - name: Compute code coverage
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Compute code coverage.
          cd tools/github
          ./coverage_convert

          # Package code coverage.
          cd generated
          tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu

      - name: Save code coverage
        uses: actions/upload-artifact@v3
        with:
          name: "Code coverage"
          path: tools/github/generated/code_coverage.tar.gz

      - name: Set base branch
        if: ${{ github.event_name == 'pull_request' }}
        run: |
          echo "BASE_BRANCH=origin/${{ github.base_ref }}" >> $GITHUB_ENV

      - name: Set base branch # if we manually dispatch or push to master
        if: ${{ github.event_name != 'pull_request' }}
        run: |
          echo "BASE_BRANCH=origin/master" >> $GITHUB_ENV

      - name: Run clang-tidy
        run: |
          source /opt/toolchain-v4/activate

          # Restrict clang-tidy results only to the modified parts
          git diff -U0 ${{ env.BASE_BRANCH }}... -- src | ./tools/github/clang-tidy/clang-tidy-diff.py -p 1 -j $THREADS -extra-arg="-DMG_CLANG_TIDY_CHECK" -path build | tee ./build/clang_tidy_output.txt

          # Fail if any warning is reported
          ! cat ./build/clang_tidy_output.txt | ./tools/github/clang-tidy/grep_error_lines.sh > /dev/null

  debug_build:
    name: "Debug build"
    runs-on: [self-hosted, Linux, X64, Diff]
    env:
      THREADS: 24
      MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
      MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}

    steps:
      - name: Set up repository
        uses: actions/checkout@v3
        with:
          # Number of commits to fetch. `0` indicates all history for all
          # branches and tags. (default: 1)
          fetch-depth: 0

      - name: Build debug binaries
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Initialize dependencies.
          ./init

          # Build debug binaries.
          cd build
          cmake ..
          make -j$THREADS

      - name: Run simulation tests
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run simulation tests.
          cd build
          ctest -R memgraph__simulation --output-on-failure -j$THREADS

      - name: Run single benchmark test
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run simulation tests.
          cd tests/mgbench
          ./benchmark.py accesscontrol/small --num-workers-for-import 1 --test-system-arg  "split-file splitfiles/accesscontrol_small.shard_configuration bolt-num-workers 1"

  release_build:
    name: "Release build"
    runs-on: [self-hosted, Linux, X64, Diff]
    env:
      THREADS: 24
      MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
      MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}

    steps:
      - name: Set up repository
        uses: actions/checkout@v3
        with:
          # Number of commits to fetch. `0` indicates all history for all
          # branches and tags. (default: 1)
          fetch-depth: 0

      - name: Build release binaries
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Initialize dependencies.
          ./init

          # Build release binaries.
          cd build
          cmake -DCMAKE_BUILD_TYPE=release ..
          make -j$THREADS

      - name: Run unit tests
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run unit tests.
          cd build
          ctest -R memgraph__unit --output-on-failure -j$THREADS

      - name: Run simulation tests
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run simulation tests.
          cd build
          ctest -R memgraph__simulation --output-on-failure -j$THREADS

      - name: Run single benchmark test
        run: |
          # Activate toolchain.
          source /opt/toolchain-v4/activate

          # Run simulation tests.
          cd tests/mgbench
          ./benchmark.py accesscontrol/small --num-workers-for-import 1 --test-system-arg  "split-file splitfiles/accesscontrol_small.shard_configuration bolt-num-workers 1"

      - name: Run e2e tests
        run: |
          # TODO(gitbuda): Setup mgclient and pymgclient properly.
          cd tests
          ./setup.sh
          source ve3/bin/activate
          cd e2e
          LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../libs/mgclient/lib python runner.py --workloads-root-directory ./distributed_queries