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
16 changes: 12 additions & 4 deletions .github/workflows/handle_potential_conflicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,10 @@ def normalize_state(state: Any) -> dict[str, Any]:


def extract_state(body: str) -> dict[str, Any]:
marker_index = body.find(COMMENT_START)
# The state block is rendered last, but comments written before that change
# start with it. Anchor on the last marker unless the body opens with one,
# so marker-like text in advisory content cannot shadow the real block.
marker_index = 0 if body.startswith(COMMENT_START) else body.rfind(COMMENT_START)
if marker_index == -1:
return normalize_state({})

Expand Down Expand Up @@ -218,9 +221,6 @@ def render_comment_body(state: dict[str, Any]) -> str:
state_json = json.dumps(state, sort_keys=True, separators=(",", ":"))
state_encoded = base64.b64encode(state_json.encode("utf8")).decode("ascii")
lines = [
COMMENT_START,
state_encoded,
COMMENT_END,
"## Potential PR merge conflicts",
"",
"This is advisory only. It does not block CI, but it marks PRs that will likely need a rebase depending on merge order.",
Expand All @@ -247,6 +247,14 @@ def render_comment_body(state: dict[str, Any]) -> str:
inbound_items = sorted(state["inbound"].values(), key=lambda item: int(item["number"]))
lines.extend(format_pr_line(item) for item in inbound_items)

# The state block goes last so notification previews start with the advisory text.
lines.extend([
"",
COMMENT_START,
state_encoded,
COMMENT_END,
])

return "\n".join(lines).rstrip() + "\n"


Expand Down
19 changes: 17 additions & 2 deletions .github/workflows/test_handle_potential_conflicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_rendered_comment_state_round_trips(self):
"outbound": [
{
"number": 12,
"title": "title with --> marker-like text",
"title": f"title with {handle_potential_conflicts.COMMENT_START} --> marker-like text",
"url": "https://github.com/dashpay/dash/pull/12",
"files": ["src/net.cpp"],
}
Expand All @@ -103,7 +103,22 @@ def test_rendered_comment_state_round_trips(self):
extracted = handle_potential_conflicts.extract_state(body)

self.assertEqual(state, extracted)
self.assertNotIn("title with --> marker-like text", body.split("-->")[0])
self.assertTrue(body.startswith("## Potential PR merge conflicts"))
self.assertTrue(body.rstrip("\n").endswith(handle_potential_conflicts.COMMENT_END))

def test_extract_state_from_legacy_marker_first_comment(self):
state = {
"outbound": [
{"number": 2, "title": "two", "url": "https://example.test/2", "files": []},
],
"inbound": {},
}
body = handle_potential_conflicts.render_comment_body(state)
marker_index = body.rfind(handle_potential_conflicts.COMMENT_START)
legacy_body = body[marker_index:] + body[:marker_index]

self.assertTrue(legacy_body.startswith(handle_potential_conflicts.COMMENT_START))
self.assertEqual(state, handle_potential_conflicts.extract_state(legacy_body))

def test_rendered_comment_escapes_markdown_content(self):
body = handle_potential_conflicts.render_comment_body({
Expand Down