build(deps): bump actions/upload-pages-artifact from 3 to 5 #108
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CI/CD Pipeline for eNI | |
| # Includes build, test, static analysis, and memory checking | |
| name: CI | |
| on: | |
| push: | |
| branches: [master, main, develop] | |
| pull_request: | |
| branches: [master, main, develop] | |
| workflow_dispatch: | |
| env: | |
| BUILD_TYPE: Release | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # ============================================================================== | |
| # Build and Test | |
| # ============================================================================== | |
| build: | |
| name: Build & Test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| include: | |
| - os: ubuntu-latest | |
| cc: gcc | |
| cxx: g++ | |
| - os: macos-latest | |
| cc: clang | |
| cxx: clang++ | |
| - os: windows-latest | |
| cc: cl | |
| cxx: cl | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies (Ubuntu) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential | |
| - name: Install dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| brew install cmake | |
| - name: Configure CMake (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| cmake -B build \ | |
| -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ | |
| -DCMAKE_C_COMPILER=${{ matrix.cc }} \ | |
| -DENI_BUILD_TESTS=ON | |
| - name: Configure CMake (Windows / MSVC) | |
| if: runner.os == 'Windows' | |
| run: | | |
| cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DENI_BUILD_TESTS=ON | |
| - name: Build | |
| shell: bash | |
| run: cmake --build build --config ${{ env.BUILD_TYPE }} -j$(nproc 2>/dev/null || sysctl -n hw.ncpu || echo 2) | |
| - name: Run Tests | |
| working-directory: build | |
| shell: bash | |
| run: ctest -C ${{ env.BUILD_TYPE }} --output-on-failure --parallel $(nproc 2>/dev/null || sysctl -n hw.ncpu || echo 2) | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-${{ matrix.os }} | |
| path: build/ | |
| retention-days: 7 | |
| # ============================================================================== | |
| # Static Analysis - Cppcheck | |
| # ============================================================================== | |
| cppcheck: | |
| name: Static Analysis (cppcheck) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install cppcheck | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cppcheck | |
| - name: Run cppcheck | |
| run: | | |
| cppcheck \ | |
| --enable=warning,performance,portability,style \ | |
| --suppress=missingIncludeSystem \ | |
| --suppress=unusedFunction \ | |
| --inline-suppr \ | |
| --std=c11 \ | |
| --error-exitcode=1 \ | |
| --force \ | |
| --quiet \ | |
| -I common/include \ | |
| -I framework/include \ | |
| -I min/include \ | |
| -I providers \ | |
| common/src \ | |
| framework/src \ | |
| min/src \ | |
| providers \ | |
| cli \ | |
| 2>&1 | tee cppcheck-report.txt | |
| - name: Upload cppcheck report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: cppcheck-report | |
| path: cppcheck-report.txt | |
| retention-days: 30 | |
| # ============================================================================== | |
| # Static Analysis - Clang-Tidy | |
| # ============================================================================== | |
| clang-tidy: | |
| name: Static Analysis (clang-tidy) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake clang clang-tidy | |
| - name: Configure CMake (generate compile_commands.json) | |
| run: | | |
| cmake -B build \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_COMPILER=clang \ | |
| -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | |
| -DENI_BUILD_TESTS=OFF | |
| - name: Run clang-tidy | |
| run: | | |
| find common/src framework/src min/src providers -name "*.c" | \ | |
| xargs clang-tidy \ | |
| -p build \ | |
| --checks='-*,bugprone-*,cert-*,clang-analyzer-*,performance-*,portability-*,-bugprone-easily-swappable-parameters' \ | |
| --warnings-as-errors='bugprone-*,cert-*,clang-analyzer-*' \ | |
| 2>&1 | tee clang-tidy-report.txt || true | |
| - name: Upload clang-tidy report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: clang-tidy-report | |
| path: clang-tidy-report.txt | |
| retention-days: 30 | |
| # ============================================================================== | |
| # Static Analysis - Clang Scan-Build | |
| # ============================================================================== | |
| scan-build: | |
| name: Static Analysis (scan-build) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake clang clang-tools | |
| - name: Run scan-build | |
| run: | | |
| scan-build \ | |
| -analyze-headers \ | |
| -enable-checker alpha.core.BoolAssignment \ | |
| -enable-checker alpha.core.CastSize \ | |
| -enable-checker alpha.core.IdenticalExpr \ | |
| -enable-checker alpha.security.ArrayBoundV2 \ | |
| -enable-checker alpha.security.MallocOverflow \ | |
| -enable-checker alpha.security.ReturnPtrRange \ | |
| -enable-checker alpha.unix.cstring.BufferOverlap \ | |
| -enable-checker alpha.unix.cstring.NotNullTerminated \ | |
| -enable-checker alpha.unix.cstring.OutOfBounds \ | |
| --use-cc=clang \ | |
| -o scan-build-report \ | |
| cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENI_BUILD_TESTS=OFF | |
| scan-build \ | |
| -analyze-headers \ | |
| --use-cc=clang \ | |
| -o scan-build-report \ | |
| cmake --build build -j$(nproc) | |
| - name: Upload scan-build report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: scan-build-report | |
| path: scan-build-report/ | |
| retention-days: 30 | |
| # ============================================================================== | |
| # Memory Check - Valgrind | |
| # ============================================================================== | |
| memcheck: | |
| name: Memory Check (Valgrind) | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential valgrind | |
| - name: Configure and Build | |
| run: | | |
| cmake -B build \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DENI_BUILD_TESTS=ON \ | |
| -DENI_ENABLE_MEMCHECK=ON | |
| cmake --build build -j$(nproc) | |
| - name: Run Valgrind memcheck on tests | |
| working-directory: build | |
| run: | | |
| mkdir -p memcheck-reports | |
| # Run memcheck on each test executable | |
| for test in $(find . -name "eni_test_*" -type f -executable); do | |
| test_name=$(basename "$test") | |
| echo "Running memcheck on $test_name..." | |
| valgrind \ | |
| --tool=memcheck \ | |
| --leak-check=full \ | |
| --show-leak-kinds=all \ | |
| --track-origins=yes \ | |
| --error-exitcode=0 \ | |
| --xml=yes \ | |
| --xml-file=memcheck-reports/${test_name}.xml \ | |
| --suppressions=../valgrind.supp \ | |
| "$test" 2>&1 | tee memcheck-reports/${test_name}.log || true | |
| done | |
| - name: Check for memory leaks | |
| working-directory: build | |
| run: | | |
| echo "=== Memory Check Summary ===" | tee memcheck-summary.txt | |
| leak_found=0 | |
| for log in memcheck-reports/*.log; do | |
| test_name=$(basename "$log" .log) | |
| # Check for definite leaks | |
| definite=$(grep -c "definitely lost:" "$log" 2>/dev/null || echo "0") | |
| possible=$(grep -c "possibly lost:" "$log" 2>/dev/null || echo "0") | |
| errors=$(grep -c "ERROR SUMMARY:" "$log" 2>/dev/null || echo "0") | |
| if grep -q "definitely lost: [1-9]" "$log" 2>/dev/null; then | |
| echo "❌ $test_name: MEMORY LEAKS DETECTED" | tee -a memcheck-summary.txt | |
| grep "definitely lost:" "$log" | tee -a memcheck-summary.txt | |
| leak_found=1 | |
| elif grep -q "Invalid read\|Invalid write\|Invalid free" "$log" 2>/dev/null; then | |
| echo "❌ $test_name: MEMORY ERRORS DETECTED" | tee -a memcheck-summary.txt | |
| leak_found=1 | |
| else | |
| echo "✅ $test_name: OK" | tee -a memcheck-summary.txt | |
| fi | |
| done | |
| echo "" | tee -a memcheck-summary.txt | |
| if [ $leak_found -eq 1 ]; then | |
| echo "⚠️ Some tests have memory issues. Review the reports." | tee -a memcheck-summary.txt | |
| else | |
| echo "✅ All tests passed memory checks!" | tee -a memcheck-summary.txt | |
| fi | |
| - name: Upload memcheck reports | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: memcheck-reports | |
| path: | | |
| build/memcheck-reports/ | |
| build/memcheck-summary.txt | |
| retention-days: 30 | |
| # ============================================================================== | |
| # Address Sanitizer | |
| # ============================================================================== | |
| asan: | |
| name: Address Sanitizer | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential | |
| - name: Configure with ASan | |
| run: | | |
| cmake -B build \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_COMPILER=gcc \ | |
| -DENI_BUILD_TESTS=ON \ | |
| -DENI_ENABLE_ASAN=ON | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Run tests with ASan | |
| working-directory: build | |
| env: | |
| ASAN_OPTIONS: detect_leaks=1:abort_on_error=1:halt_on_error=0 | |
| run: | | |
| ctest --output-on-failure --parallel $(nproc) 2>&1 | tee asan-report.txt | |
| - name: Upload ASan report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: asan-report | |
| path: build/asan-report.txt | |
| retention-days: 30 | |
| # ============================================================================== | |
| # Undefined Behavior Sanitizer | |
| # ============================================================================== | |
| ubsan: | |
| name: Undefined Behavior Sanitizer | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential | |
| - name: Configure with UBSan | |
| run: | | |
| cmake -B build \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_COMPILER=gcc \ | |
| -DENI_BUILD_TESTS=ON \ | |
| -DENI_ENABLE_UBSAN=ON | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Run tests with UBSan | |
| working-directory: build | |
| env: | |
| UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=0 | |
| run: | | |
| ctest --output-on-failure --parallel $(nproc) 2>&1 | tee ubsan-report.txt | |
| - name: Upload UBSan report | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: ubsan-report | |
| path: build/ubsan-report.txt | |
| retention-days: 30 | |
| # ============================================================================== | |
| # Code Coverage | |
| # ============================================================================== | |
| coverage: | |
| name: Code Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential lcov | |
| - name: Configure with coverage | |
| run: | | |
| cmake -B build \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_COMPILER=gcc \ | |
| -DENI_BUILD_TESTS=ON \ | |
| -DENI_ENABLE_COVERAGE=ON | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Run tests | |
| working-directory: build | |
| run: ctest --output-on-failure --parallel $(nproc) | |
| - name: Generate coverage report | |
| working-directory: build | |
| run: | | |
| lcov --capture --directory . --output-file coverage.info --rc lcov_branch_coverage=1 | |
| lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage_filtered.info --rc lcov_branch_coverage=1 | |
| genhtml coverage_filtered.info --output-directory coverage_report --branch-coverage | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: build/coverage_report/ | |
| retention-days: 30 | |
| - name: Coverage summary | |
| working-directory: build | |
| run: | | |
| lcov --summary coverage_filtered.info | |
| # ============================================================================== | |
| # Summary Job | |
| # ============================================================================== | |
| summary: | |
| name: CI Summary | |
| runs-on: ubuntu-latest | |
| needs: [build, cppcheck, clang-tidy, scan-build, memcheck, asan, ubsan, coverage] | |
| if: always() | |
| steps: | |
| - name: Check job results | |
| run: | | |
| echo "## CI/CD Pipeline Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Build & Test | ${{ needs.build.result == 'success' && '✅ Passed' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| cppcheck | ${{ needs.cppcheck.result == 'success' && '✅ Passed' || '⚠️ Issues' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| clang-tidy | ${{ needs.clang-tidy.result == 'success' && '✅ Passed' || '⚠️ Issues' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| scan-build | ${{ needs.scan-build.result == 'success' && '✅ Passed' || '⚠️ Issues' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Valgrind memcheck | ${{ needs.memcheck.result == 'success' && '✅ Passed' || '⚠️ Issues' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| AddressSanitizer | ${{ needs.asan.result == 'success' && '✅ Passed' || '⚠️ Issues' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| UBSanitizer | ${{ needs.ubsan.result == 'success' && '✅ Passed' || '⚠️ Issues' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Coverage | ${{ needs.coverage.result == 'success' && '✅ Generated' || '⚠️ Failed' }} |" >> $GITHUB_STEP_SUMMARY |