diff --git a/.github/workflows/ci-code.yml b/.github/workflows/ci-code.yml index b3e3abb5..e4e8dc77 100644 --- a/.github/workflows/ci-code.yml +++ b/.github/workflows/ci-code.yml @@ -106,20 +106,5 @@ jobs: - uses: actions/checkout@v4 - name: Build and run coverage run: | - docker build -f Dockerfile.debian -t profanity-cov . - docker run -v ${{ github.workspace }}/coverage:/coverage profanity-cov bash -c ' - ./bootstrap.sh - ./configure --enable-coverage --enable-otr --enable-pgp --enable-omemo --enable-plugins - make -j$(nproc) - make check || true - make check-functional-parallel || true - lcov --capture --directory . --output-file /coverage/coverage.info \ - --rc branch_coverage=1 \ - --ignore-errors inconsistent - lcov --remove /coverage/coverage.info \ - "/usr/include/*" "*/tests/*" \ - --output-file /coverage/coverage.info \ - --rc branch_coverage=1 \ - --ignore-errors inconsistent,empty,unused - lcov --summary /coverage/coverage.info - ' \ No newline at end of file + docker build -f Dockerfile.arch -t profanity-cov . + docker run profanity-cov ./ci-build.sh --coverage-only \ No newline at end of file diff --git a/ci-build.sh b/ci-build.sh index a971b3cd..5fbc955d 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -110,6 +110,17 @@ num_cores() # Run test failure detection verification first verify_test_failure_detection +# Parse arguments +COVERAGE_ONLY=no +for arg in "$@"; do + case "$arg" in + --coverage-only) + COVERAGE_ONLY=yes + shift + ;; + esac +done + ./bootstrap.sh tests=() @@ -210,7 +221,7 @@ build_and_test() { exit 1 fi - # Run unit tests under Valgrind + # Run unit tests local unit_passed=0 unit_failed=0 if [ "$run_valgrind" = "yes" ]; then echo "--> Running unit tests under Valgrind..." @@ -225,13 +236,21 @@ build_and_test() { echo "ERROR: Valgrind unit tests failed (exit code $valgrind_exit)" exit 1 fi - # Extract unit test counts from cmocka output - unit_passed=$(grep -E "^\[ PASSED \] [0-9]+ test" unit-tests-output.log | grep -oE "[0-9]+" | head -1) - unit_failed=$(grep -E "^\[ FAILED \] [0-9]+ test" unit-tests-output.log | grep -oE "[0-9]+" | head -1) - [ -z "$unit_passed" ] && unit_passed=0 - [ -z "$unit_failed" ] && unit_failed=0 - echo "UNIT_TESTS: passed=$unit_passed failed=$unit_failed" + else + echo "--> Running unit tests..." + $MAKE tests/unittests/unittests + tests/unittests/unittests 2>&1 | tee unit-tests-output.log + if [ ${PIPESTATUS[0]} -ne 0 ]; then + echo "ERROR: Unit tests failed" + exit 1 + fi fi + # Extract unit test counts from cmocka output + unit_passed=$(grep -E "^\[ PASSED \] [0-9]+ test" unit-tests-output.log | grep -oE "[0-9]+" | head -1) + unit_failed=$(grep -E "^\[ FAILED \] [0-9]+ test" unit-tests-output.log | grep -oE "[0-9]+" | head -1) + [ -z "$unit_passed" ] && unit_passed=0 + [ -z "$unit_failed" ] && unit_failed=0 + echo "UNIT_TESTS: passed=$unit_passed failed=$unit_failed" # Set build index for port allocation: build 1 uses ports 5230-5233, # build 2 uses 5234-5237, etc. This prevents port conflicts in parallel builds. @@ -286,6 +305,13 @@ build_and_test() { fi ./profanity -v + + # Save coverage.info before cleanup (for CI artifact) + if [ "$run_coverage" = "yes" ] && [ -f coverage.info ]; then + cp coverage.info ../coverage.info + echo "Coverage report saved to coverage.info" + fi + $MAKE clean cd .. @@ -300,40 +326,52 @@ build_and_test() { } > "$log_file" 2>&1 } -# Run all 4 configurations in parallel +# Run configurations # Coverage enabled only for build 1 (Full) - it has most code paths echo echo "=== Start build ===" echo -echo "Starting 4 parallel build configurations..." -echo -pids=() -for idx in 1 2 3 4; do - if [ $idx -le ${#tests[@]} ]; then - # All builds run Valgrind - if [ "$ARCH" = "linux" ]; then - run_valgrind="yes" - if [ $idx -eq 1 ]; then - extra_flags="--enable-valgrind --enable-coverage" - run_coverage="yes" + +if [ "$COVERAGE_ONLY" = "yes" ]; then + echo "Running coverage-only mode (build 1 only)..." + echo + run_valgrind="no" + run_coverage="yes" + extra_flags="--enable-coverage" + build_and_test "${tests[0]}" "$* $extra_flags" "1" "$run_valgrind" "$run_coverage" & + pids=("$!") + echo " → Build 1: ${tests[0]} [+Coverage]" +else + echo "Starting 4 parallel build configurations..." + echo + pids=() + for idx in 1 2 3 4; do + if [ $idx -le ${#tests[@]} ]; then + # All builds run Valgrind + if [ "$ARCH" = "linux" ]; then + run_valgrind="yes" + if [ $idx -eq 1 ]; then + extra_flags="--enable-valgrind --enable-coverage" + run_coverage="yes" + else + extra_flags="--enable-valgrind" + run_coverage="no" + fi else - extra_flags="--enable-valgrind" + extra_flags="" + run_valgrind="no" run_coverage="no" fi - else - extra_flags="" - run_valgrind="no" - run_coverage="no" + build_and_test "${tests[$((idx-1))]}" "$* $extra_flags" "$idx" "$run_valgrind" "$run_coverage" & + pids+=("$!") + flags_desc="" + [ "$run_valgrind" = "yes" ] && flags_desc="Valgrind" + [ "$run_coverage" = "yes" ] && flags_desc="${flags_desc:+$flags_desc+}Coverage" + [ -n "$flags_desc" ] && flags_desc=" [+$flags_desc]" + echo " → Build $idx: ${tests[$((idx-1))]}$flags_desc" fi - build_and_test "${tests[$((idx-1))]}" "$* $extra_flags" "$idx" "$run_valgrind" "$run_coverage" & - pids+=("$!") - flags_desc="" - [ "$run_valgrind" = "yes" ] && flags_desc="Valgrind" - [ "$run_coverage" = "yes" ] && flags_desc="${flags_desc:+$flags_desc+}Coverage" - [ -n "$flags_desc" ] && flags_desc=" [+$flags_desc]" - echo " → Build $idx: ${tests[$((idx-1))]}$flags_desc" - fi -done + done +fi echo # Wait for all builds and check exit codes @@ -389,5 +427,9 @@ if [ ${#failed_builds[@]} -gt 0 ]; then echo "RESULT: FAILED (builds ${failed_builds[*]})" exit 1 else - echo "RESULT: ALL 4 BUILDS PASSED ✓" + if [ "$COVERAGE_ONLY" = "yes" ]; then + echo "RESULT: COVERAGE BUILD PASSED ✓" + else + echo "RESULT: ALL 4 BUILDS PASSED ✓" + fi fi