name: Coverage Measurement (Fixed -fPIC) on: push: branches: [ main, develop, consolidate-side-enum ] pull_request: branches: [ main, develop ] workflow_dispatch: env: CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 # Key fix: Override static linking for coverage builds RUSTFLAGS: "-C relocation-model=pic -C prefer-dynamic=yes -C target-cpu=native -A warnings -A clippy::all" jobs: coverage: name: Code Coverage with Tarpaulin runs-on: ubuntu-latest timeout-minutes: 60 steps: - name: Checkout code uses: actions/checkout@v4 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - name: Cache cargo registry uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-registry- - name: Cache cargo build uses: actions/cache@v3 with: path: target key: ${{ runner.os }}-cargo-build-coverage-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-build-coverage- ${{ runner.os }}-cargo-build- - name: Install cargo-tarpaulin run: cargo install cargo-tarpaulin --version "^0.27" - name: Verify tarpaulin configuration run: | echo "Checking tarpaulin.toml exists..." test -f tarpaulin.toml && echo "✅ Found tarpaulin.toml" || echo "❌ Missing tarpaulin.toml" echo "Current RUSTFLAGS: $RUSTFLAGS" - name: Run coverage on trading engine packages run: | cargo tarpaulin \ --config tarpaulin.toml \ --packages types,health,unified-config,error-handling \ --out Html \ --out Xml \ --out Lcov \ --output-dir target/coverage/trading_engine \ --timeout 180 \ --target-dir target/tarpaulin-trading_engine \ --verbose - name: Run coverage on service packages run: | cargo tarpaulin \ --config tarpaulin.toml \ --packages trading-engine,market-data,ai-intelligence \ --out Html \ --out Xml \ --out Lcov \ --output-dir target/coverage/services \ --timeout 300 \ --target-dir target/tarpaulin-services \ --verbose continue-on-error: true - name: Generate coverage summary run: | echo "## Coverage Report Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Function to extract coverage from XML extract_coverage() { local xml_file="$1" if [[ -f "$xml_file" ]]; then local coverage=$(grep -o 'line-rate="[^"]*"' "$xml_file" | head -1 | grep -o '[0-9.]*' | head -1) if [[ -n "$coverage" ]]; then echo "scale=2; $coverage * 100" | bc -l 2>/dev/null || echo "N/A" else echo "N/A" fi else echo "N/A" fi } # Trading engine packages coverage trading_engine_coverage=$(extract_coverage "target/coverage/trading_engine/cobertura.xml") echo "- Trading engine packages: ${trading_engine_coverage}%" >> $GITHUB_STEP_SUMMARY # Service packages coverage services_coverage=$(extract_coverage "target/coverage/services/cobertura.xml") echo "- Service packages: ${services_coverage}%" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Available Reports" >> $GITHUB_STEP_SUMMARY echo "- HTML reports uploaded as artifacts" >> $GITHUB_STEP_SUMMARY echo "- XML reports for coverage analysis" >> $GITHUB_STEP_SUMMARY echo "- LCOV reports for integration with other tools" >> $GITHUB_STEP_SUMMARY - name: Upload coverage reports uses: actions/upload-artifact@v3 with: name: coverage-reports-fixed path: | target/coverage/*/ !target/coverage/**/target/ retention-days: 30 - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: files: target/coverage/trading_engine/lcov.info,target/coverage/services/lcov.info flags: unittests name: codecov-umbrella fail_ci_if_error: false - name: Coverage gate check run: | # Extract trading engine coverage percentage if [[ -f "target/coverage/trading_engine/cobertura.xml" ]]; then TRADING_ENGINE_COVERAGE=$(grep -o 'line-rate="[^"]*"' target/coverage/trading_engine/cobertura.xml | head -1 | grep -o '[0-9.]*' | head -1) TRADING_ENGINE_COVERAGE_PCT=$(echo "scale=2; $TRADING_ENGINE_COVERAGE * 100" | bc -l) echo "Trading engine coverage: ${TRADING_ENGINE_COVERAGE_PCT}%" # Set minimum coverage threshold for trading engine packages MIN_COVERAGE=70 if (( $(echo "$TRADING_ENGINE_COVERAGE_PCT >= $MIN_COVERAGE" | bc -l) )); then echo "✅ Coverage gate passed: ${TRADING_ENGINE_COVERAGE_PCT}% >= ${MIN_COVERAGE}%" else echo "❌ Coverage gate failed: ${TRADING_ENGINE_COVERAGE_PCT}% < ${MIN_COVERAGE}%" echo "::warning::Coverage below minimum threshold of ${MIN_COVERAGE}%" fi else echo "⚠️ No coverage data found for trading engine packages" fi