Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions scripts/check-issue-links.py
Original file line number Diff line number Diff line change
Expand Up @@ -1399,15 +1399,29 @@ def _mention_detail(refs: Refs, number: int) -> str:
return "; ".join(clauses)


#: A release version an issue's own text names, e.g. `Release v0.3.46`. It is read
#: A release version an issue's own **title** names, e.g. `Release v0.3.46`. It is read
#: because it is the one fact an open issue carries about what finishes *it*: a PR's own
#: title never reaches `judge_issues`, so "was the declaring PR a bump?" cannot be answered
#: here at all, while "does this issue's completion name a published artifact?" can.
#:
#: The title and not the body, because the two say different things: a title says what an
#: issue **is**, while a body says what it was **seen in**. An ordinary issue cites the
#: release it observed its defect on, and reading that as the artifact that finishes it
#: hands the reader a published version for work that has nothing to do with one - the
#: reading then exits 0 and invites a close over work that is not done. Measured over the
#: repository's last 200 issues: 34 name a version, 26 of them in the title and 8 only in
#: the body, and three of those 8 driven through `judge_issues` each took the artifact
#: remedy for a merge about something else. An issue naming its version only in the body
#: therefore keeps the remedy it had.
_RELEASE_VERSION = re.compile(r"\bv\d+\.\d+\.\d+\b")


def release_version(*texts: str | None) -> str | None:
"""The release version this issue's own text names, or `None` when it names none."""
"""The release version the given text names, or `None` when it names none.

Which text is the caller's decision, not this function's: `judge_issues` passes the
issue's title alone, and the reason is stated on `_RELEASE_VERSION`.
"""
for text in texts:
if not text:
continue
Expand Down Expand Up @@ -1521,9 +1535,7 @@ def judge_issues(
)
continue
if refs.declared_merged or refs.declared_abandoned:
detail = _declined_detail(
refs, number, release_version(issue.get("title"), issue.get("body"))
)
detail = _declined_detail(refs, number, release_version(issue.get("title")))
elif refs.mentioned_landed or refs.mentioned_abandoned or refs.mentioned_open:
detail = _mention_detail(refs, number)
else:
Expand Down
42 changes: 42 additions & 0 deletions tests/test_check_issue_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -2854,3 +2854,45 @@ def test_judge_issues_reads_the_version_off_the_issue_it_is_judging(mod) -> None
rows = {row.number: row for row in mod.judge_issues(issues, refs, {})}
assert "check-release-published.py v0.3.46" in rows[2781].detail
assert "check-release-published" not in rows[2778].detail


# --- the title declares the version, the body only mentions one --------------------
#
# The artifact remedy belongs where an issue **declares** the release it is about, and is
# wrong where its body merely cites the release it was **seen in**: that version is already
# published, so the printed reading exits 0 and invites a close over work it never
# described. Measured over the repository's last 200 issues, 34 name a version and 8 of
# them name it only in the body - each of those took the artifact sentence before this
# gate, for a merge that had done something else.


def test_a_version_in_the_body_does_not_make_an_issue_a_release_issue(mod) -> None:
issues = [
{
"number": 2760,
"title": "The actionlint step's download has no retry, so one upstream 504 reddens master for hours",
"body": "master has failed its Test workflow since a85b1ddd; v0.3.41 stepped on the download.",
"created_at": "2026-11-08T10:00:00Z",
}
]
refs = {2760: mod.Refs(declared_merged={2759})}
rows = {row.number: row for row in mod.judge_issues(issues, refs, {})}
assert "check-release-published" not in rows[2760].detail
assert "either close this issue with the reading that says the work is done" in rows[2760].detail


def test_the_title_is_what_declares_the_version_and_the_body_is_not(mod) -> None:
body = "master has failed its Test workflow since a85b1ddd; v0.3.41 stepped on the download."
issues = [
{"number": 2781, "title": "Release v0.3.46", "body": body, "created_at": "2026-11-09T17:35:22Z"},
{
"number": 2760,
"title": "The actionlint step's download has no retry, so one upstream 504 reddens master for hours",
"body": body,
"created_at": "2026-11-08T10:00:00Z",
},
]
refs = {2781: mod.Refs(declared_merged={2782}), 2760: mod.Refs(declared_merged={2759})}
rows = {row.number: row for row in mod.judge_issues(issues, refs, {})}
assert "check-release-published.py v0.3.46" in rows[2781].detail
assert "check-release-published" not in rows[2760].detail
Loading