name: libyang CI
on:
  push:
    branches:
      - master
      - devel
  pull_request:
    branches:
      - master
      - devel

jobs:
  build-unix:
    name: ${{ matrix.config.name }}
    runs-on: ${{ matrix.config.os }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - {
            name: "Release, gcc",
            os: "ubuntu-22.04",
            build-type: "Release",
            cc: "gcc",
            options: "-DENABLE_TESTS=ON",
            packager: "sudo apt-get",
            # no expect because stdout seems to be redirected
            packages: "libcmocka-dev libxxhash-dev shunit2",
            snaps: "",
            build-cmd: "make"
          }
          - {
            name: "Release, clang",
            os: "ubuntu-22.04",
            build-type: "Release",
            cc: "clang",
            options: "-DENABLE_TESTS=ON",
            packager: "sudo apt-get",
            packages: "libcmocka-dev libxxhash-dev shunit2",
            snaps: "",
            build-cmd: "make"
          }
          - {
            name: "Debug, gcc",
            os: "ubuntu-22.04",
            build-type: "Debug",
            cc: "gcc",
            options: "",
            packager: "sudo apt-get",
            packages: "libcmocka-dev libxxhash-dev valgrind shunit2",
            snaps: "",
            build-cmd: "make"
          }
          - {
            name: "Debug, clang",
            os: "ubuntu-22.04",
            build-type: "Debug",
            cc: "clang",
            options: "",
            packager: "sudo apt-get",
            # no valgrind because it does not support DWARF5 yet generated by clang 14
            packages: "libcmocka-dev libxxhash-dev shunit2",
            snaps: "",
            build-cmd: "make"
          }
          - {
            name: "Release, macOS 14, clang",
            os: "macos-14",
            build-type: "Release",
            cc: "clang",
            options: "-DENABLE_TESTS=ON -DPATH_EXPECT=",
            packager: "brew",
            packages: "cmocka xxhash shunit2 tcl-tk",
            snaps: "",
            build-cmd: "make"
          }
          - {
            name: "ASAN and UBSAN",
            os: "ubuntu-22.04",
            build-type: "Debug",
            cc: "clang",
            options: "-DCMAKE_C_FLAGS=-fsanitize=address,undefined -DENABLE_TESTS=ON -DENABLE_VALGRIND_TESTS=OFF",
            packager: "sudo apt-get",
            packages: "libcmocka-dev libxxhash-dev",
            snaps: "",
            build-cmd: "make"
          }
          - {
            name: "ABI Check",
            os: "ubuntu-22.04",
            build-type: "ABICheck",
            cc: "gcc",
            options: "",
            packager: "sudo apt-get",
            packages: "libcmocka-dev libxxhash-dev abi-dumper abi-compliance-checker",
            snaps: "core universal-ctags",
            build-cmd: "make abi-check"
          }
          - {
            name: "DEB Package",
            os: "ubuntu-22.04",
            build-type: "Release",
            cc: "gcc",
            options: "",
            packager: "sudo apt-get",
            packages: "cmake debhelper libcmocka-dev libxxhash-dev python3-pip",
            snaps: "",
            build-cmd: ""
          }

    steps:
      - uses: actions/checkout@main
        with:
          fetch-depth: 100

      - name: Deps-packages
        shell: bash
        run: |
          ${{ matrix.config.packager }} update
          if ${{ matrix.config.packages != '' }}
            then ${{ matrix.config.packager }} install ${{ matrix.config.packages }}
          fi
          if ${{ matrix.config.snaps != '' }}
            then sudo snap install ${{ matrix.config.snaps }}
          fi

      - name: Deps-uncrustify
        shell: bash
        working-directory: ${{ github.workspace }}
        run: |
          git clone --branch uncrustify-0.77.1 https://github.com/uncrustify/uncrustify
          cd uncrustify
          mkdir build
          cd build
          CC=${{ matrix.config.cc }} cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ..
          make
          sudo make install
        if: ${{ matrix.config.name == 'Debug, gcc' }}

      - name: Build-and-install-package
        shell: bash
        working-directory: ${{ github.workspace }}
        run: |
          pip install apkg
          apkg system-setup
          apkg build
          apkg install
        if: ${{ matrix.config.name == 'DEB Package' }}

      - name: Configure
        shell: bash
        working-directory: ${{ github.workspace }}
        run: |
          mkdir build
          cd build
          CC=${{ matrix.config.cc }} cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.build-type }} ${{ matrix.config.options }} ..
        if: ${{ matrix.config.name != 'DEB Package' }}

      - name: Build
        shell: bash
        working-directory: ${{ github.workspace }}/build
        run: |
          export LC_ALL=C.UTF-8
          export PATH=/snap/bin:${{ github.workspace }}/coverity-tools/bin:$PATH
          ${{ matrix.config.build-cmd }}
        if: ${{ matrix.config.name != 'DEB Package' }}

      - name: Test
        shell: bash
        working-directory: ${{ github.workspace }}/build
        run: ctest --output-on-failure
        if: ${{ matrix.config.name != 'DEB Package' }}

  build-windows:
    name: ${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: "Windows 2022 MSVC 16 LF"
            os: windows-2022
            triplet: x64-windows
            build_type: Release
            generators: "Visual Studio 17 2022"
            autocrlf: input
            eol: lf

          - name: "Windows 2022 MSVC 16 no autoCRLF"
            os: windows-2022
            triplet: x64-windows
            build_type: Release
            generators: "Visual Studio 17 2022"

    steps:
      - name: Unix line endings in git
        if: matrix.autocrlf
        run: |
          git config --global core.autocrlf ${{ matrix.autocrlf }}

      - name: Unix line endings in git
        if: matrix.eol
        run: |
          git config --global core.eol ${{ matrix.eol }}

      - uses: actions/checkout@main

      - name: Get number of CPU cores
        id: cpu-cores
        uses: SimenB/github-actions-cpu-cores@v1

      - name: pin CMake to the latest 3.x series
        uses: jwlawson/actions-setup-cmake@09fd9b0fb3b239b4b68d9256cd65adf8d6b91da0
        with:
          cmake-version: '3.31.6'

      - name: Install Windows dependencies
        run: vcpkg install --triplet=${{ matrix.triplet }} pcre2 pthreads dirent dlfcn-win32 cmocka getopt xxhash

      - name: Configure
        shell: bash
        run: |
          cmake \
            -S '${{ github.workspace }}/' \
            -B '${{ github.workspace }}/'../build \
            -G '${{ matrix.generators }}' \
            -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
            -DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} \
            -DCMAKE_TOOLCHAIN_FILE=${VCPKG_INSTALLATION_ROOT//\\//}/scripts/buildsystems/vcpkg.cmake \
            -DENABLE_TESTS=ON \
            '-DCMAKE_INSTALL_PREFIX:PATH=${{ github.workspace }}'/../target

      - name: Build
        working-directory: '${{ github.workspace }}/../build'
        run: cmake --build . -j${{ steps.cpu-cores.outputs.count }} --config ${{ matrix.build_type }}

      - name: Test
        working-directory: '${{ github.workspace }}/../build'
        run: ctest --output-on-failure -j${{ steps.cpu-cores.outputs.count }} --build-config ${{ matrix.build_type }}

      - name: Install
        working-directory: '${{ github.workspace }}/../build'
        run: cmake --install . --strip
