Skip to content

Coverage enforcement workflow + auto-updating badge#36

Merged
tinder-maxwellelliott merged 3 commits into
mainfrom
coverage-enforcement
May 20, 2026
Merged

Coverage enforcement workflow + auto-updating badge#36
tinder-maxwellelliott merged 3 commits into
mainfrom
coverage-enforcement

Conversation

@tinder-maxwellelliott

Copy link
Copy Markdown
Collaborator

Summary

  • New Python coverage tool (tools/coverage/check_coverage.py) that drives bazel coverage + xctest + llvm-cov directly, working around the known rules_swift gap where the standard bazel coverage merger writes a 0-byte coverage.dat for swift_test on macOS. Defaults to a 90% line-coverage threshold and exits non-zero below it.
  • CI gains a coverage job (failing PRs that drop below 90%) and a publish-coverage-badge job that pushes a shields.io endpoint-format JSON to a badges branch on push to main. README now shows the live coverage badge.
  • Closed the gap from 78.43% → 95.14% by adding CoreLibraryImpTests (Files/Clock/UUID/Log/ProcessInfo/Network/Shell/Keychain wrappers + URLSession extension), expanding JSONWebTokenServiceTests for the enterprise audience claim + error paths, and re-recording 24 iTunesConnectServiceTests snapshots (the deprecated httpShouldUsePipelining field is no longer dumped by newer macOS SDKs — same make record_snapshots flow as before). Total: 65 → 102 Swift tests, plus 30 Python self-tests for the coverage tool.

Coverage report

Sources/CoreLibrary/Keychain.swift                                        92.00%
Sources/CoreLibrary/Shell.swift                                           92.04%
Sources/SignHereLibrary/Commands/CreateProvisioningProfileCommand.swift   93.12%
Sources/SignHereLibrary/Commands/CreateKeychainCommand.swift              95.97%
Sources/SignHereLibrary/Services/iTunesConnectService.swift               96.15%
Sources/CoreLibrary/Network.swift                                         96.67%
(remaining files at 100.00%)
TOTAL: 95.14% (1429/1502)  threshold=90.00%  -> PASS

Badge

After the first push-to-main merge, the README badge will live-update from https://raw.githubusercontent.com/Tinder/sign-here/badges/coverage.json — generated by the new publish-coverage-badge job on the badges orphan branch.

How to run locally

make coverage           # collect + enforce 90% (also: bazel run //tools/coverage:check_coverage)
make coverage_tool_test # Python self-tests

Test plan

  • CI coverage job passes (target: 95.14% ≥ 90%)
  • CI tests and tests-bzlmod jobs still pass on the re-recorded snapshots
  • After merge to main, the publish-coverage-badge job creates the badges branch with coverage.json
  • README's "Coverage" badge resolves to the published shields.io endpoint
  • Lowering the threshold (--threshold 99 locally) demonstrates the FAIL path

🤖 Generated with Claude Code

tinder-maxwellelliott and others added 3 commits May 20, 2026 13:03
… to 95%

Adds a tools/coverage/check_coverage.py CLI that drives the macOS
swift_test -> LCOV pipeline directly (working around the rules_swift
gap where `bazel coverage` writes 0-byte coverage.dat files), enforces a
90% line-coverage floor, and can emit a shields.io endpoint-format
badge.

CI gains a `coverage` job that fails the build under 90% and uploads
both LCOV and badge artifacts, plus a `publish-coverage-badge` job that
commits the badge JSON to a `badges` branch on push to main. The README
template now links the shields.io endpoint, and README.md was
regenerated.

To get the project above the threshold, this commit also adds
CoreLibraryImpTests covering FilesImp, ClockImp, UUIDImp, LogImp,
ProcessInfoImp, NetworkImp, ShellImp, the URLSession DataTaskHandler
extension, and KeychainImp, plus expands JSONWebTokenServiceTests for
the enterprise audience claim and both error paths. Snapshot fixtures
in iTunesConnectServiceTests were re-recorded for the
httpShouldUsePipelining removal in newer macOS SDKs.

Coverage: 78.43% -> 95.14%; 65 -> 102 Swift tests; 30 Python self-tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The badge is consumed exclusively by the publish-coverage-badge job,
which already runs only on push to main. Gating the badge generation
and artifact upload behind the same condition keeps PR runs leaner and
makes it explicit that PRs cannot influence the published badge value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 24 snapshots in the prior commit were re-recorded on a host with
Xcode 26's Swift runtime, which has dropped `httpShouldUsePipelining`
from `dump(URLRequest)` output. CI runs on macos-15-arm64 with an older
Xcode that still emits the field, so the regenerated snapshots caused
22 spurious failures on every PR/main run.

Restoring the original snapshots makes CI green again. The coverage
tool itself does not depend on these snapshots — it just runs the
existing test target — so the 95.14% measurement is unchanged on
CI's runtime.

Developers on Xcode 26+ can still re-record locally with
`make record_snapshots`, but should avoid committing the resulting diff
until the CI runner image picks up a matching Xcode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tinder-maxwellelliott
tinder-maxwellelliott merged commit 8b7c1d6 into main May 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant