test: raise coverage to 100% (and fix output_to_json metric gating)#522
Merged
Conversation
Add unit tests covering all previously-uncovered branches in auth.py, env.py, and stale_repos.py, and bump --cov-fail-under from 80 to 100 in the Makefile so the threshold matches reality. New tests: - auth_to_github raises ValueError when github3.login returns None - get_env_vars loads the .env file when test=False - get_inactive_repos honors EXEMPT_REPOS - get_days_since_last_release handles TypeError and empty iterators - get_days_since_last_pr handles empty iterators - get_active_date raises on unsupported ACTIVITY_METHOD - output_to_json emits daysSinceLastRelease/daysSinceLastPR when present - output_to_json appends to GITHUB_OUTPUT when set - set_repo_data swallows and logs GitHubException on release/pr lookup Also adds a [report] exclude_lines block to .coveragerc covering 'pragma: no cover' (already implicit) and 'if __name__ == "__main__":'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Zack Koppert <zkoppert@github.com>
output_to_json was gating the optional release/pr JSON fields on literal "release" and "pr" keys in repo_data, but set_repo_data never produces those keys - it always writes "days_since_last_release" and "days_since_last_pr". As a result, the JSON output (including the value written to $GITHUB_OUTPUT) silently dropped both fields for every real caller, even when ADDITIONAL_METRICS was configured. The markdown output was already correct because it gates on additional_metrics, not the dict keys. Mirror the markdown writer: thread additional_metrics through to output_to_json and gate the optional fields on it. The main() caller already has the list, so this is a no-op for any caller that does not opt in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Zack Koppert <zkoppert@github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR raises the project’s CI coverage bar to 100% by adding targeted unit tests for previously uncovered branches, and it fixes a production bug where output_to_json silently omitted optional daysSinceLastRelease / daysSinceLastPR fields even when ADDITIONAL_METRICS was configured. The JSON gating logic is aligned with the markdown writer by explicitly threading additional_metrics into output_to_json from main().
Changes:
- Add unit tests to cover previously uncovered branches in
auth.py,env.py, andstale_repos.py. - Fix
output_to_jsonto include optional JSON fields based onadditional_metrics(matching markdown semantics). - Enforce 100% coverage (
--cov-fail-under=100) and exclude__main__blocks via.coveragerc.
Show a summary per file
| File | Description |
|---|---|
test_stale_repos.py |
Adds branch-coverage tests for exempt repos parsing, exception paths, JSON optional-metric output, $GITHUB_OUTPUT writing, and set_repo_data exception handling. |
test_env.py |
Adds coverage for loading .env via load_dotenv when test=False. |
test_auth.py |
Adds coverage for the github3.login(...) returns None failure path. |
stale_repos.py |
Fixes JSON optional-metric gating by passing and honoring additional_metrics in output_to_json. |
Makefile |
Raises coverage enforcement threshold from 80% to 100%. |
.coveragerc |
Adds report-time exclusions for pragma: no cover and if __name__ == "__main__":. |
Copilot's findings
- Files reviewed: 6/6 changed files
- Comments generated: 0
jmeridth
approved these changes
Jun 12, 2026
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.
Pull Request
Proposed Changes
stale-reposships with--cov-fail-under=80, and the working tree sat at ~90% line coverage with eleven branches uncovered acrossauth.py,env.py, andstale_repos.py. Raising coverage to 100% also matches the in-flight 100%-coverage push across the rest of the github-community-projects fleet.While writing the masking-free tests I found a latent bug in
output_to_jsonthat all three review models independently flagged:output_to_jsonwas gating the optionaldaysSinceLastRelease/daysSinceLastPRJSON fields on literal"release"/"pr"keys in the per-repo dict, butset_repo_data(the only production producer of those dicts) only ever writes"days_since_last_release"/"days_since_last_pr". The result: the JSON output, including the value written to$GITHUB_OUTPUT, silently dropped both fields for every real caller, even whenADDITIONAL_METRICSwas configured. Markdown output was unaffected because it gates onadditional_metricsdirectly. I fixed this tightly-coupled bug in a separate commit by threadingadditional_metricsintooutput_to_jsonand mirroring the markdown writer's gate.What changed
[report] exclude_linesblock to.coveragerccoveringpragma: no cover(already implicit) andif __name__ == .__main__.:.--cov-fail-underfrom80to100in the Makefile.output_to_jsonto gate optional JSON fields onadditional_metrics(separate commit), matching the markdown writer's semantics. Themain()caller now passesadditional_metricstooutput_to_json.New test coverage (per uncovered branch)
auth.pytest_auth_to_github_raises_when_connection_is_noneenv.pytest_get_env_vars_loads_dotenv_when_not_teststale_repos.pytest_exempt_repos_env_var_is_parsed_and_appliedstale_repos.pytest_returns_none_on_type_error(get_days_since_last_release)stale_repos.pytest_returns_none_when_no_releasesstale_repos.pytest_returns_none_when_no_pull_requestsstale_repos.pytest_unsupported_activity_method_raises_value_errorstale_repos.pytest_includes_release_and_pr_keys_when_additional_metrics_set+test_release_only_metric_omits_pr_fieldstale_repos.pytest_writes_to_github_output_when_env_var_setstale_repos.pytest_github_exception_on_release_is_loggedstale_repos.pytest_github_exception_on_pr_is_loggedBefore / after coverage
auth.pyenv.pymarkdown.pystale_repos.pyReadiness Checklist
Author/Contributor
make lintand fix any issues that you have introducedmake testand ensure you have test coverage for the lines you are introducingTesting
make lint- all 5 linters pass (flake8 syntax + warnings, isort, pylint 10.00/10, mypy, black). No suppression comments added.make test- 53 tests pass (6 sub-tests),Required test coverage of 100% reached. Total coverage: 100.00%. Verified on the Python 3.11 baseline used by the Makefile and on the Python 3.12 fallback that uv selected on this machine.output_to_jsongating bug; the fix landed in this PR as a separate commit.Rollout
output_to_jsonbug fix. WithADDITIONAL_METRICSunset (the default), the JSON output and$GITHUB_OUTPUTvalue are byte-identical to today. WithADDITIONAL_METRICS=releaseorpr, the JSON now correctly includesdaysSinceLastRelease/daysSinceLastPR, which downstream consumers (e.g., scripts that read$GITHUB_OUTPUT) may have been silently missing.--cov-fail-under=80→100) means any future PR that drops coverage will fail CI rather than slipping in unnoticed. This is the desired behavior and matches the fleet convention.Tradeoffs / Alternatives considered
output_to_jsonfix I considered (a) gating on"days_since_last_release" in repo_data(always true postset_repo_data, would force the field into the output of callers who don't opt in - silent behavior change) and (b) threadingadditional_metricsthrough (chosen, mirrorsmarkdown.py, no behavior change for non-opt-in callers).if __name__ == "__main__":line I considered adding# pragma: no coverinline instead of anexclude_linesentry. The.coveragercrule is more discoverable and matches conventions in other repos in the fleet.