ci: gate PRs on 100% patch coverage + 95% project floor #25
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: coverage | |
| on: | |
| pull_request: | |
| branches: [master, main] | |
| push: | |
| branches: [master, main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| coverage: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| path: worker | |
| # Full history so diff-cover can resolve origin/<base_ref>. | |
| fetch-depth: 0 | |
| - uses: actions/checkout@v4 | |
| with: | |
| repository: InstaNode-dev/common | |
| path: common | |
| continue-on-error: true | |
| - uses: actions/checkout@v4 | |
| with: | |
| repository: InstaNode-dev/proto | |
| path: proto | |
| continue-on-error: true | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: worker/go.mod | |
| - name: Generate coverage | |
| working-directory: worker | |
| run: go test ./... -short -coverprofile=coverage.out -covermode=atomic || true | |
| - uses: codecov/codecov-action@v4 | |
| with: | |
| files: worker/coverage.out | |
| flags: worker | |
| fail_ci_if_error: false | |
| # ------------------------------------------------------------------ | |
| # Org patch-coverage mandate: every changed line in a PR diff must be | |
| # covered by a test (100%), and the project floor stays >=95%. | |
| # Tool: diff-cover (https://github.com/Bachmann1234/diff-cover). The | |
| # "Generate coverage" step is `|| true` so it still produces | |
| # coverage.out even on a flaky test — the gate reads that file. | |
| # ------------------------------------------------------------------ | |
| - uses: actions/setup-python@v5 | |
| if: github.event_name == 'pull_request' | |
| with: | |
| python-version: '3.12' | |
| - name: Install diff-cover + cobertura converter | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| pip install diff-cover | |
| go install github.com/boumenot/gocover-cobertura@latest | |
| - name: Convert coverage to Cobertura | |
| if: github.event_name == 'pull_request' | |
| working-directory: worker | |
| run: $(go env GOPATH)/bin/gocover-cobertura < coverage.out > coverage.xml | |
| - name: Patch coverage gate (100% of changed lines) | |
| if: github.event_name == 'pull_request' | |
| working-directory: worker | |
| run: | | |
| git fetch origin "${{ github.base_ref }}" --depth=1 || true | |
| diff-cover coverage.xml \ | |
| --compare-branch="origin/${{ github.base_ref }}" \ | |
| --fail-under=100 | |
| - name: Project coverage floor (>=95% total) | |
| if: github.event_name == 'pull_request' | |
| working-directory: worker | |
| run: | | |
| total=$(go tool cover -func=coverage.out | tail -1 | awk '{print $3}' | tr -d '%') | |
| echo "Total project coverage: ${total}%" | |
| awk -v t="$total" 'BEGIN { exit (t+0 >= 95) ? 0 : 1 }' \ | |
| || { echo "::error::Project coverage ${total}% is below the 95% floor"; exit 1; } |