test(#432): add cargo-llvm-cov coverage with 95% threshold #1
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
| name: CI | |
| on: | |
| push: | |
| pull_request: | |
| jobs: | |
| contract: | |
| name: Rust contract | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust stable + wasm32 target | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: contracts/subscription | |
| - name: Build (wasm32 release) | |
| run: cargo build --manifest-path contracts/subscription/Cargo.toml --target wasm32-unknown-unknown --release | |
| - name: Test & summary | |
| run: | | |
| set -o pipefail | |
| cargo test --manifest-path contracts/subscription/Cargo.toml 2>&1 \ | |
| | tee /tmp/contract-test-output.txt | |
| echo "--- Test summary ---" | |
| grep -E "^test result|FAILED|ok$" /tmp/contract-test-output.txt || true | |
| # Issue #432 – 95% coverage threshold enforcement | |
| contract-coverage: | |
| name: Rust contract coverage (≥95%) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust stable + llvm-tools | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: llvm-tools-preview | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: contracts/subscription | |
| - name: Install cargo-llvm-cov | |
| run: cargo install cargo-llvm-cov --locked | |
| - name: Generate coverage report (LCOV + HTML) | |
| run: make test-coverage | |
| - name: Check 95% line coverage threshold | |
| run: | | |
| # Extract line coverage % from lcov.info and fail if below 95 | |
| LCOV_FILE="contracts/target/lcov.info" | |
| if [ ! -f "$LCOV_FILE" ]; then | |
| echo "ERROR: lcov.info not found at $LCOV_FILE" >&2 | |
| exit 1 | |
| fi | |
| LINES_FOUND=$(grep -E "^LF:" "$LCOV_FILE" | awk -F: '{sum += $2} END {print sum}') | |
| LINES_HIT=$(grep -E "^LH:" "$LCOV_FILE" | awk -F: '{sum += $2} END {print sum}') | |
| if [ -z "$LINES_FOUND" ] || [ "$LINES_FOUND" -eq 0 ]; then | |
| echo "ERROR: No coverage data found in lcov.info" >&2 | |
| exit 1 | |
| fi | |
| COVERAGE=$(echo "scale=2; $LINES_HIT * 100 / $LINES_FOUND" | bc) | |
| echo "Line coverage: ${COVERAGE}% (${LINES_HIT}/${LINES_FOUND} lines)" | |
| # Use awk for floating-point comparison (bc outputs e.g. "97.42") | |
| PASS=$(echo "$COVERAGE" | awk '{print ($1 >= 95) ? "yes" : "no"}') | |
| if [ "$PASS" != "yes" ]; then | |
| echo "FAIL: Coverage ${COVERAGE}% is below the required 95% threshold." >&2 | |
| exit 1 | |
| fi | |
| echo "PASS: Coverage ${COVERAGE}% meets the 95% threshold." | |
| - name: Upload LCOV to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| files: contracts/target/lcov.info | |
| flags: contract | |
| name: sorobanpay-contract | |
| fail_ci_if_error: false | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload HTML report as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: contract-coverage-html | |
| path: contracts/target/coverage-html/ | |
| - name: Upload LCOV report as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: contract-coverage-lcov | |
| path: contracts/target/lcov.info | |
| # Issue #431 – Integration test suite on local Soroban node | |
| contract-integration: | |
| name: Smart contract integration tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust stable + wasm32 target | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: contracts/subscription | |
| - name: Install Stellar CLI | |
| run: cargo install --locked stellar-cli --features opt | |
| - name: Make integration test script executable | |
| run: chmod +x scripts/integration-test.sh | |
| - name: Run integration tests (local Soroban node via Docker) | |
| run: bash scripts/integration-test.sh | |
| env: | |
| DOCKER_BUILDKIT: 1 | |
| backend-integration: | |
| name: Backend integration tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: backend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: backend | |
| - name: Run integration tests | |
| run: npm run test:integration | |
| working-directory: backend | |
| # Issue #433 – Frontend unit tests + coverage (>80%) | |
| frontend: | |
| name: Frontend type check, unit tests & coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: frontend | |
| - name: Type check | |
| run: npm run type-check | |
| working-directory: frontend | |
| - name: Run unit tests with coverage | |
| run: npm run test:ci | |
| working-directory: frontend | |
| - name: Upload frontend coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| files: frontend/coverage/lcov.info | |
| flags: frontend | |
| name: sorobanpay-frontend | |
| fail_ci_if_error: false | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload coverage HTML report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: frontend-coverage-html | |
| path: frontend/coverage/ | |
| frontend-typecheck: | |
| name: Frontend strict type check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: frontend | |
| - name: Type check (fail on errors) | |
| run: npm run type-check | |
| working-directory: frontend |