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
37 changes: 35 additions & 2 deletions scripts/check-issue-links.py
Original file line number Diff line number Diff line change
Expand Up @@ -1399,7 +1399,25 @@ def _mention_detail(refs: Refs, number: int) -> str:
return "; ".join(clauses)


def _declined_detail(refs: Refs, number: int) -> str:
#: A release version an issue's own text 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.
_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."""
for text in texts:
if not text:
continue
found = _RELEASE_VERSION.search(text)
if found:
return found.group(0)
return None


def _declined_detail(refs: Refs, number: int, release: str | None = None) -> str:
"""What to do about declarers that closed with no open one left.

Two facts, one sentence each, because the remedies are opposite: a **merged**
Expand Down Expand Up @@ -1435,6 +1453,19 @@ def _declined_detail(refs: Refs, number: int) -> str:
"finish the work: do not close this issue on that merge, state here what "
"it still leaves"
)
elif release is not None:
clauses.append(
f"{_numbers(refs.declared_merged)} declared `Closes #{number}` and {verb} "
f"merged, and what finishes this issue is the published `{release}`, not "
"that merge - a declaring pull request can move the version string while "
"nothing is released, so the merge is not the reading that settles it. "
f"`uv run --no-sync python3 scripts/check-release-published.py {release}` "
"is the reading: green across the platform matrix is what says the work "
"is done, and this issue may be "
"closed on that reading; anything else, or no answer at all, means it is "
"not done - do not close this issue on the merge, state here what it "
"still leaves"
)
else:
clauses.append(
f"{_numbers(refs.declared_merged)} declared `Closes #{number}` and {verb} "
Expand Down Expand Up @@ -1490,7 +1521,9 @@ def judge_issues(
)
continue
if refs.declared_merged or refs.declared_abandoned:
detail = _declined_detail(refs, number)
detail = _declined_detail(
refs, number, release_version(issue.get("title"), issue.get("body"))
)
elif refs.mentioned_landed or refs.mentioned_abandoned or refs.mentioned_open:
detail = _mention_detail(refs, number)
else:
Expand Down
51 changes: 51 additions & 0 deletions tests/test_check_issue_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -2803,3 +2803,54 @@ def test_the_ledger_path_is_overridable(mod, monkeypatch):
monkeypatch.setenv("EMRG_RANTS", "/tmp/from-env.jsonl")
assert mod.rants_path() == Path("/tmp/from-env.jsonl")
assert mod.rants_path("/tmp/wins.jsonl") == Path("/tmp/wins.jsonl")


# --- an issue finished by a published artifact, not by a merge ---------------------
#
# A release issue is the case where "a declaring PR merged" and "the work is done" come
# apart: the bump PR carries the closing keyword, so its merge closes the issue while
# nothing has been tagged or published. The row then offered "the reading that says the
# work is done" for work that had not begun. The fix reads the one fact the issue itself
# carries - the release version it names - and sends the reader to that artifact's own
# reading instead of inferring completion from the merge.


def test_a_release_issue_is_not_told_to_close_on_its_bump_merge(mod) -> None:
detail = mod._declined_detail(mod.Refs(declared_merged={2782}), 2781, "v0.3.46")
assert "scripts/check-release-published.py v0.3.46" in detail
assert "either close this issue with the reading that says the work is done" not in detail


def test_an_ordinary_issue_keeps_the_remedy_it_had(mod) -> None:
detail = mod._declined_detail(mod.Refs(declared_merged={2779}), 2778)
assert "either close this issue with the reading that says the work is done" in detail
assert "check-release-published" not in detail


def test_the_artifact_is_what_changes_the_sentence_not_the_branch(mod) -> None:
refs = mod.Refs(declared_merged={2782})
withheld = mod._declined_detail(refs, 2781)
assert withheld == mod._declined_detail(refs, 2781, None)
assert withheld != mod._declined_detail(refs, 2781, "v0.3.46")


def test_the_release_version_is_read_only_where_it_is_one(mod) -> None:
assert mod.release_version("Release v0.3.46") == "v0.3.46"
assert mod.release_version("an ordinary title") is None
assert mod.release_version(None, "") is None
assert mod.release_version("0.3.46") is None
assert mod.release_version("xv0.3.46y") is None


def test_judge_issues_reads_the_version_off_the_issue_it_is_judging(mod) -> None:
issues = [
{"number": 2781, "title": "Release v0.3.46", "created_at": "2026-11-09T17:35:22Z"},
{"number": 2778, "title": "A change that needs no release", "created_at": "2026-11-09T15:49:24Z"},
]
refs = {
2781: mod.Refs(declared_merged={2782}),
2778: mod.Refs(declared_merged={2779}),
}
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
9 changes: 5 additions & 4 deletions tests/test_printed_commands_carry_the_python_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@
what keeps the clause off prose: "update `VERSION_SOURCES` in `scripts/bump-version.py`"
ends at the file name and is not a thing to run, while `scripts/check-vote-count.py <PR>` is.

What the clause reads on this tree, measured 2026-10-24: **39** command-shaped mentions, in
eight tools - `bump-version.py` 2, `cast-vote.py` 8, `check-merge-freshness.py` 8,
`check-merge-landed.py` 1, `check-merge-sequence.py` 1, `check-release-published.py` 1,
`check-vote-count.py` 1, `review-queue.py` 17. This number has gone down as well as up, and
What the clause reads on this tree, measured 2026-11-10: **40** command-shaped mentions, in
nine tools - `bump-version.py` 2, `cast-vote.py` 8, `check-issue-links.py` 1,
`check-merge-freshness.py` 8, `check-merge-landed.py` 1, `check-merge-sequence.py` 1,
`check-release-published.py` 1, `check-vote-count.py` 1, `review-queue.py` 17. This number
has gone down as well as up, and
it goes down the way it went up: a *printed remedy* is a printed command either way, so a
remedy deleted together with the tool that printed it takes its mention with it.
`review-queue.py` carried a second `abstain` branch - a head pushed below a window whose
Expand Down
Loading