Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 129 additions & 31 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,26 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install tools
run: |
sudo apt-get update
sudo apt-get install -y clang-tidy clang-format

- name: Check formatting
continue-on-error: true
run: |
echo "⚠️ Formatting check (non-blocking)"
find src includes -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' \) \
-exec clang-format --dry-run --Werror {} + || true


- name: Install dependencies
run: |
sudo apt-get install -y libssl-dev ninja-build

- name: Configure CMake
run: cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
run: cmake -B build -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

- name: Run clang-tidy
continue-on-error: true
run: |
Expand All @@ -46,7 +50,7 @@ jobs:
name: ${{ matrix.os }} - ${{ matrix.compiler }}
needs: lint
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
Expand All @@ -57,46 +61,46 @@ jobs:
c_compiler: gcc
cpp_compiler: g++
coverage: true

- os: ubuntu-latest
compiler: clang
c_compiler: clang
cpp_compiler: clang++
coverage: false

# Windows builds
- os: windows-latest
compiler: msvc
c_compiler: cl
cpp_compiler: cl
coverage: false

# macOS builds
- os: macos-latest
compiler: clang
c_compiler: clang
cpp_compiler: clang++
coverage: false

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake lcov ninja-build
sudo apt-get install -y build-essential cmake lcov ninja-build libssl-dev

- name: Install macOS dependencies
if: runner.os == 'macOS'
run: brew install ninja
run: brew install ninja openssl

- name: Setup MSVC
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1

- name: Cache CMake build
uses: actions/cache@v4
with:
Expand All @@ -106,7 +110,7 @@ jobs:
key: ${{ matrix.os }}-${{ matrix.compiler }}-${{ hashFiles('**/CMakeLists.txt') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.compiler }}-

- name: Configure CMake
run: >
cmake -B build -G Ninja
Expand All @@ -115,58 +119,152 @@ jobs:
-DCMAKE_BUILD_TYPE=Release
-DBUILD_TESTING=ON
-DENABLE_COVERAGE=${{ matrix.coverage && 'ON' || 'OFF' }}

- name: Build
run: cmake --build build --config Release --parallel

- name: Run tests

- name: Build tests explicitly
run: cmake --build build --target nexus_tests --config Release

- name: List build directory (Unix)
if: runner.os != 'Windows'
run: |
echo "=== Build directory structure ==="
find build -type f -name "nexus_tests*" -o -name "*.so" -o -name "*.dylib" 2>/dev/null || echo "No test files found"
echo ""
echo "=== Tests directory ==="
ls -la build/tests/ 2>/dev/null || echo "No tests directory"

- name: List build directory (Windows)
if: runner.os == 'Windows'
shell: powershell
run: |
Write-Host "=== Build directory structure ==="
Get-ChildItem -Recurse build -Filter "nexus_tests*" -ErrorAction SilentlyContinue | Select-Object FullName
Write-Host ""
Write-Host "=== Tests directory ==="
Get-ChildItem build\tests -ErrorAction SilentlyContinue | Select-Object Name

- name: Run tests directly (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
echo "=== Testing direct execution ==="
if [ -f "build/tests/nexus_tests" ]; then
echo "Found: build/tests/nexus_tests"
./build/tests/nexus_tests --list-tests
./build/tests/nexus_tests --reporter console
elif [ -f "build/bin/nexus_tests" ]; then
echo "Found: build/bin/nexus_tests"
./build/bin/nexus_tests --list-tests
./build/bin/nexus_tests --reporter console
else
echo "ERROR: nexus_tests executable not found!"
exit 1
fi

- name: Run tests directly (Windows)
if: runner.os == 'Windows'
shell: powershell
run: |
Write-Host "=== Testing direct execution ==="
$testPaths = @(
"build\tests\Release\nexus_tests.exe",
"build\tests\nexus_tests.exe",
"build\bin\Release\nexus_tests.exe",
"build\Release\nexus_tests.exe"
)

$found = $false
foreach ($path in $testPaths) {
if (Test-Path $path) {
Write-Host "Found: $path"
& $path --list-tests
& $path --reporter console
$found = $true
break
}
}

if (-not $found) {
Write-Host "ERROR: nexus_tests.exe not found in any expected location!"
exit 1
}

- name: Run CTest (Unix)
if: runner.os != 'Windows'
working-directory: build
run: |
echo "=== Running CTest ==="
ctest --output-on-failure --verbose -C Release

- name: Run CTest (Windows)
if: runner.os == 'Windows'
working-directory: build
run: ctest --output-on-failure --verbose -C Release

- name: Generate coverage
if: matrix.coverage && hashFiles('test/**') != ''
if: matrix.coverage
working-directory: build
run: |
# Check if tests ran successfully
if [ ! -f "tests/nexus_tests" ] && [ ! -f "bin/nexus_tests" ]; then
echo "⚠️ No test executable found, skipping coverage"
exit 0
fi

# Generate coverage
echo "=== Generating coverage report ==="
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' '*/test/*' --output-file coverage.info
lcov --remove coverage.info '/usr/*' '*/tests/*' '*/_deps/*' --output-file coverage.info
echo "=== Coverage Summary ==="
lcov --summary coverage.info
lcov --list coverage.info

- name: Upload to Coveralls
if: matrix.coverage && hashFiles('test/**') != ''
if: matrix.coverage && hashFiles('build/coverage.info') != ''
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
file: build/coverage.info
format: lcov


- name: Upload coverage artifact
if: matrix.coverage && hashFiles('build/coverage.info') != ''
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: build/coverage.info
retention-days: 7

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.os }}-${{ matrix.compiler }}
path: build/Testing/
retention-days: 7

- name: Upload build artifacts
if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'gcc'
uses: actions/upload-artifact@v4
with:
name: binaries-linux
path: build/bin/
path: |
build/bin/
build/lib/
retention-days: 30

build-summary:
name: Build Summary
needs: build
runs-on: ubuntu-latest
if: always()

steps:
- name: Check build status
run: |
if [ "${{ needs.build.result }}" != "success" ]; then
echo "::error::One or more builds failed"
exit 1
fi
echo "✅ All builds passed successfully"
echo "✅ All builds passed successfully"
62 changes: 43 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,24 +98,6 @@ FetchContent_Declare(

FetchContent_MakeAvailable(curl)


# Catch2 (tests)
if (BUILD_TESTING)
find_package(Catch2 3 QUIET)
if (NOT Catch2_FOUND)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.5.1
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(Catch2)
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
endif ()
include(CTest)
include(Catch)
endif ()

# ------------------ Core library ------------------
add_library(nexus_core SHARED
includes/Logger/Logger.hpp
Expand Down Expand Up @@ -194,6 +176,18 @@ add_library(nexus_core SHARED
includes/mainframe/service/ForegroundServiceHost.hpp
)

set_target_properties(nexus_core PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib
)

target_include_directories(nexus_core
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>
Expand Down Expand Up @@ -525,4 +519,34 @@ set(CPACK_SOURCE_IGNORE_FILES
*.swp
*.swo
*~
)
)

# ------------------ Coverage Configuration ------------------
if (ENABLE_COVERAGE)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
add_library(coverage_config INTERFACE)

target_compile_options(coverage_config INTERFACE
--coverage
-O0
-g
)

target_link_options(coverage_config INTERFACE
--coverage
)

# Link coverage direct aan nexus_core
target_link_libraries(nexus_core PRIVATE coverage_config)

message(STATUS "Code coverage enabled")
else()
message(WARNING "Code coverage requested but compiler is not GCC or Clang")
add_library(coverage_config INTERFACE)
endif()
else()
# Maak een dummy interface als coverage uit staat
add_library(coverage_config INTERFACE)
endif()

add_subdirectory(tests)
Loading
Loading