fix: preserve existing PR titles (#1236)

Keep automatic existing-PR updates from retitling pull requests, while documenting the explicit edit path for intentional title changes.
This commit is contained in:
Johannes du Plessis 2026-05-04 09:35:08 -07:00 • committed by GitHub
parent 6579b84b74
commit 30530bf4d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 12 additions and 9 deletions

View file

@ -141,10 +141,10 @@ Make HTTP requests (GET, POST, PUT, DELETE, etc.) to APIs. Use this for API call
Do not use this tool to create or update the pull request for completed code changes. Use `commit_and_open_pr` for that workflow so commits are pushed and GitHub authentication is handled correctly. For other PR-related actions, use the dedicated GitHub PR tools when available.
#### `commit_and_open_pr`
Commits all changes, pushes to a branch, and opens a **draft** GitHub PR. If a PR already exists for the branch, it is updated instead of recreated.
Commits all changes, pushes to a branch, and opens a **draft** GitHub PR. If a PR already exists for the branch, it is reused and its existing title is preserved; the PR body may be refreshed to reflect the latest work.
#### `edit_pull_request`
Edits the title and/or body of an existing GitHub Pull Request. Use this to update a PR description after creation — for example, after multiple iterations of changes. Requires `pr_number` and at least one of `title` or `body`.
Edits the title and/or body of an existing GitHub Pull Request. Use this to deliberately update a PR title when the overall PR contents have changed enough that the existing title is stale or misleading, or to update a PR description after creation. Requires `pr_number` and at least one of `title` or `body`.
#### `linear_comment`
Posts a comment to a Linear ticket given a `ticket_id`. Call this **after** `commit_and_open_pr` to notify stakeholders that the work is done and include the PR link. You can tag Linear users with `@username` (their Linear display name). Example: "I've completed the implementation and opened a PR: <pr_url>. Hey @username, let me know if you have any feedback!".
@ -284,6 +284,7 @@ When you have completed your implementation, follow these steps in order:
2. **Review your changes**: Review the diff to ensure correctness. Verify no regressions or unintended modifications.
3. **Submit via `commit_and_open_pr` tool**: Call this tool as the final step.
If a PR already exists for the branch, `commit_and_open_pr` preserves the existing PR title. Do not use repeated `commit_and_open_pr` calls to retitle an existing PR; use `edit_pull_request` with `title` only when the current title is stale or misleading for the overall PR contents.
**PR Title** (under 70 characters):
```

View file

@ -233,7 +233,6 @@ async def create_github_pr(
repo_name=repo_name,
github_token=token,
pr_number=pr_number,
title=title,
body=body,
)
if not updated:
@ -426,10 +425,10 @@ async def _update_github_pr(
repo_name: str,
github_token: str,
pr_number: int | None,
title: str,
body: str,
title: str | None = None,
) -> bool:
"""Update an existing PR's title and body via PATCH."""
"""Update an existing PR via PATCH."""
if pr_number is None:
logger.warning("Cannot update PR: pr_number is None")
return False
@ -439,16 +438,19 @@ async def _update_github_pr(
"X-GitHub-Api-Version": "2022-11-28",
}
try:
payload = {"body": body}
if title is not None:
payload["title"] = title
response = await http_client.patch(
f"https://api.github.com/repos/{repo_owner}/{repo_name}/pulls/{pr_number}",
headers=headers,
json={"title": title, "body": body},
json=payload,
)
except httpx.HTTPError:
logger.warning("Failed to update PR #%s", pr_number, exc_info=True)
return False
if response.status_code == 200: # noqa: PLR2004
logger.info("Updated existing PR #%s with new title and body", pr_number)
logger.info("Updated existing PR #%s", pr_number)
return True
logger.warning(
"Failed to update PR #%s (%s): %s",

View file

@ -189,7 +189,7 @@ def test_create_pr_adds_label_on_existing_pr(monkeypatch: pytest.MonkeyPatch) ->
assert calls[2] == (
"PATCH",
"https://api.github.com/repos/o/r/pulls/7",
{"title": "feat: test", "body": "body"},
{"body": "body"},
)
assert calls[3] == (
"POST",
@ -242,7 +242,7 @@ def test_create_pr_returns_failure_when_existing_pr_update_fails(
(
"PATCH",
"https://api.github.com/repos/o/r/pulls/7",
{"title": "feat: test", "body": "body"},
{"body": "body"},
),
]