Visitar URL original
feat: say why a check was skipped in --format json (#605) · commit-check/commit-check@f643ecd · GitHub
Skip to content

Commit f643ecd

Browse files
authored
feat: say why a check was skipped in --format json (#605)
A skipped check now carries a reason when the author is on an ignore_authors list, e.g. "author dependabot[bot] is in [commit].ignore_authors", so consumers such as the GitHub Action can tell users why nothing was validated. Co-authored-by: Xianpeng Shen <3353385+shenxianpeng@users.noreply.github.com>
1 parent 1be275f commit f643ecd

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

‎commit_check/api.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"error": "<error description>",
3030
"suggest": "<how to fix>",
3131
"fix": "<the corrected value when the fix is unambiguous; else empty>",
32+
"reason": "<why a skipped check did not run, when known; else empty>",
3233
},
3334
...
3435
]

‎commit_check/engine.py‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ class CheckOutcome:
147147
fix: str = ""
148148
rule_id: str = ""
149149
docs_url: str = ""
150+
# Why a skipped check did not run, when commit-check knows (the author
151+
# is on an ``ignore_authors`` list); empty otherwise.
152+
reason: str = ""
150153

151154
def to_dict(self) -> dict[str, str]:
152155
"""Serialise to a plain dict (suitable for JSON encoding)."""
@@ -159,6 +162,7 @@ def to_dict(self) -> dict[str, str]:
159162
"suggest": self.suggest,
160163
"fix": self.fix,
161164
"docs_url": self.docs_url,
165+
"reason": self.reason,
162166
}
163167

164168

@@ -221,6 +225,10 @@ def __init__(self, rule: ValidationRule):
221225
# collection. Text-mode validation skips the extra lookups (e.g. a
222226
# git subprocess for the branch name) and keeps values empty.
223227
self._collect_value: bool = False
228+
# Why the rule declined to run, when the reason is something the
229+
# user configured (an ignored author). A bare "skipped" leaves the
230+
# reader guessing whether the policy was bypassed on purpose.
231+
self._skip_reason: str = ""
224232

225233
@abstractmethod
226234
def validate(self, context: ValidationContext) -> ValidationResult:
@@ -300,6 +308,7 @@ def _author_in_ignore_list(self, context: ValidationContext) -> bool:
300308

301309
current_author = self._resolve_current_author(context)
302310
if current_author and current_author in ignore_authors:
311+
self._skip_reason = f"author {current_author} is in [commit].ignore_authors"
303312
return True
304313

305314
# Check co-authors from the commit message body
@@ -312,7 +321,13 @@ def _author_in_ignore_list(self, context: ValidationContext) -> bool:
312321
message,
313322
re.MULTILINE,
314323
)
315-
return any(co_author.strip() in ignore_authors for co_author in co_authors)
324+
for co_author in co_authors:
325+
if co_author.strip() in ignore_authors:
326+
self._skip_reason = (
327+
f"co-author {co_author.strip()} is in [commit].ignore_authors"
328+
)
329+
return True
330+
return False
316331

317332
@staticmethod
318333
def _get_commit_body(context: ValidationContext) -> str:
@@ -362,6 +377,9 @@ def _should_skip_branch_validation(self, context: ValidationContext) -> bool:
362377
if ignore_authors:
363378
current_author = self._resolve_current_author(context)
364379
if current_author and current_author in ignore_authors:
380+
self._skip_reason = (
381+
f"author {current_author} is in [branch].ignore_authors"
382+
)
365383
return True
366384
return context.piped_name is None and not has_commits()
367385

@@ -1727,6 +1745,7 @@ def validate_all_detailed(self, context: ValidationContext) -> list[CheckOutcome
17271745
value="" if skipped else (validator._checked_value or ""),
17281746
rule_id=rule.rule_id or "",
17291747
docs_url=rule.docs_url or "",
1748+
reason=validator._skip_reason if skipped else "",
17301749
)
17311750
)
17321751

‎tests/engine_test.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,9 @@ def test_branch_ignored_author_uses_commit_author_when_no_stdin(self):
552552
result = validator.validate(context)
553553
# Skipped — the commit's author (dependabot[bot]) is in ignore_authors
554554
assert result == ValidationResult.SKIP
555+
assert validator._skip_reason == (
556+
"author dependabot[bot] is in [branch].ignore_authors"
557+
)
555558

556559

557560
class TestAuthorValidator:
@@ -1722,6 +1725,29 @@ def test_validate_all_detailed_branch_reports_branch_name(self):
17221725
outcomes = engine.validate_all_detailed(context)
17231726
assert outcomes[0].status == "pass"
17241727
assert outcomes[0].value == "feature/add-login"
1728+
assert outcomes[0].reason == ""
1729+
1730+
@pytest.mark.benchmark
1731+
def test_validate_all_detailed_skip_reports_ignored_author(self):
1732+
"""A check skipped for an ignored author says so, not just "skip"."""
1733+
rules = [ValidationRule(check="message", regex=r"^feat:")]
1734+
engine = ValidationEngine(rules)
1735+
context = ValidationContext(
1736+
rev="HEAD",
1737+
config={"commit": {"ignore_authors": ["dependabot[bot]"]}},
1738+
)
1739+
1740+
with patch(
1741+
"commit_check.engine.get_commit_info", return_value="dependabot[bot]"
1742+
):
1743+
outcomes = engine.validate_all_detailed(context)
1744+
1745+
assert outcomes[0].status == "skip"
1746+
assert outcomes[0].value == ""
1747+
assert outcomes[0].reason == (
1748+
"author dependabot[bot] is in [commit].ignore_authors"
1749+
)
1750+
assert outcomes[0].to_dict()["reason"] == outcomes[0].reason
17251751

17261752
@pytest.mark.benchmark
17271753
def test_validation_engine_validate_all_fail(self):
@@ -2193,6 +2219,9 @@ def test_co_author_in_ignore_list_skips_validation(self):
21932219
with patch("commit_check.engine.get_commit_info", return_value="other-author"):
21942220
result = validator.validate(context)
21952221
assert result == ValidationResult.SKIP
2222+
assert validator._skip_reason == (
2223+
"co-author coderabbitai[bot] is in [commit].ignore_authors"
2224+
)
21962225

21972226
@pytest.mark.benchmark
21982227
def test_co_author_not_in_ignore_list_does_not_skip(self):

0 commit comments

Comments
 (0)