Coverage enforcement workflow + auto-updating badge#36
Merged
Conversation
… 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>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bazel coverage+xctest+llvm-covdirectly, working around the known rules_swift gap where the standardbazel coveragemerger writes a 0-bytecoverage.datforswift_teston macOS. Defaults to a 90% line-coverage threshold and exits non-zero below it.coveragejob (failing PRs that drop below 90%) and apublish-coverage-badgejob that pushes a shields.io endpoint-format JSON to abadgesbranch on push tomain. README now shows the live coverage badge.CoreLibraryImpTests(Files/Clock/UUID/Log/ProcessInfo/Network/Shell/Keychain wrappers +URLSessionextension), expandingJSONWebTokenServiceTestsfor the enterprise audience claim + error paths, and re-recording 24iTunesConnectServiceTestssnapshots (the deprecatedhttpShouldUsePipeliningfield is no longer dumped by newer macOS SDKs — samemake record_snapshotsflow as before). Total: 65 → 102 Swift tests, plus 30 Python self-tests for the coverage tool.Coverage report
Badge
After the first push-to-
mainmerge, the README badge will live-update fromhttps://raw.githubusercontent.com/Tinder/sign-here/badges/coverage.json— generated by the newpublish-coverage-badgejob on thebadgesorphan branch.How to run locally
Test plan
coveragejob passes (target: 95.14% ≥ 90%)testsandtests-bzlmodjobs still pass on the re-recorded snapshotsmain, thepublish-coverage-badgejob creates thebadgesbranch withcoverage.json--threshold 99locally) demonstrates the FAIL path🤖 Generated with Claude Code