diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32705b7..34f38f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,8 @@ env: RUST_BACKTRACE: short CARGO_INCREMENTAL: 1 RUSTFLAGS: "-C debuginfo=0" + # Reviewed baseline: 76.366%. Lower only through an explicit pull request. + COVERAGE_MIN_LINES: 76 concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} @@ -97,13 +99,23 @@ jobs: - name: Generate coverage report run: cargo llvm-cov --all-features --lcov --output-path lcov.info + - name: Enforce line coverage floor + run: cargo llvm-cov report --fail-under-lines "$COVERAGE_MIN_LINES" + - name: Upload coverage to Codecov + id: codecov + continue-on-error: true uses: codecov/codecov-action@v5 with: files: lcov.info - fail_ci_if_error: false + fail_ci_if_error: true verbose: true + - name: Report Codecov service failure + if: steps.codecov.outcome == 'failure' + run: | + echo "::warning title=Codecov reporting failed::The source coverage gate passed, but the external report could not be uploaded." + build: name: Build - ${{ matrix.os }} needs: test @@ -144,8 +156,8 @@ jobs: echo "Tests failed" exit 1 fi - # Coverage is informational, don't fail on it - if [[ "${{ needs.coverage.result }}" == "failure" ]]; then - echo "Coverage failed (non-blocking)" + if [[ "${{ needs.coverage.result }}" != "success" ]]; then + echo "Coverage regression or report generation failed" + exit 1 fi echo "CI passed!" diff --git a/README.md b/README.md index 44bc991..6c0e5ee 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,22 @@ Handler organization: For the authoritative per-endpoint mapping see the bundled OpenAPI spec at [`tests/fixtures/cloud_openapi.json`](tests/fixtures/cloud_openapi.json). +## Test Coverage + +CI enforces a repository-wide line-coverage floor of 76%, based on the reviewed +76.366% all-features baseline. Reproduce the gate locally with: + +```bash +cargo llvm-cov --all-features --lcov --output-path lcov.info --fail-under-lines 76 +``` + +The floor is intentionally stored in `.github/workflows/ci.yml`, so lowering it +requires an explicit reviewed change. Raise it as coverage improves. Patch +coverage is not initially enforced: the deterministic repository-wide gate is +the source-of-truth check, while Codecov remains an external reporting service. +An upload outage is reported as a CI warning without being confused with a +source coverage regression. + ## Documentation - [API Documentation](https://docs.rs/redis-cloud)