Skip to content

Commit cc275de

Browse files
committed
feat(release): auto-add RC task in process-backports when adding PRs
- Modify `process_backports.py` to check if a pending RC task exists when backports are added. - If no pending RC task exists, auto-add the next `Tag RC<N>` task to the checklist. - Add `test_process_backports_add_backports_and_auto_add_rc_task` to `process_backports_test.py` to verify this behavior.
1 parent 41f820e commit cc275de

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

tests/tools/private/release/process_backports_test.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,64 @@ def mock_resolve(items):
247247
self.mock_git.commit.assert_not_called()
248248
self.mock_git.push.assert_not_called()
249249

250+
@patch("tools.private.release.process_backports.datetime")
251+
def test_process_backports_add_backports_and_auto_add_rc_task(self, mock_datetime):
252+
mock_datetime.date.today.return_value = datetime.date(2026, 7, 1)
253+
args = argparse.Namespace(
254+
issue=123,
255+
remote="origin",
256+
dry_run=False,
257+
add=[124],
258+
triggering_comment=None,
259+
)
260+
self.mock_gh.get_issue_title.return_value = "Release 2.0.0"
261+
self.mock_gh.get_issue_body.return_value = """
262+
## Checklist
263+
- [x] Prepare Release | status=done pr=#122 commit=abcdef12
264+
- [x] Create Release branch | status=done branch=release/2.0 commit=abcdef12
265+
- [x] Tag RC0 | status=done tag=2.0.0-rc0 commit=abcdef12
266+
- [ ] Tag Final
267+
268+
## Backports
269+
"""
270+
self.mock_git.get_remote_tags.return_value = ["2.0.0-rc0"]
271+
self.mock_git.get_commit_sha.return_value = "12345678"
272+
self.mock_git.get_commit_message.return_value = 'Cherry-pick "fix bug"'
273+
274+
def mock_resolve(items):
275+
for item in items:
276+
if item.pr_ref == "#124":
277+
item.commit = "abcdef12"
278+
item.status = "done"
279+
return items
280+
281+
self.mock_gh.get_merge_commits_for_prs.side_effect = mock_resolve
282+
self.mock_git.sort_commits_chronologically.return_value = ["abcdef12"]
283+
284+
result = ProcessBackports(args, self.mock_git, self.mock_gh).run()
285+
286+
self.assertEqual(result, 0)
287+
288+
# update_issue_body should be called twice:
289+
# 1. When adding backports and auto-adding Tag RC1 task.
290+
# 2. When updating the backport status to done.
291+
self.assertEqual(self.mock_gh.update_issue_body.call_count, 2)
292+
293+
call1_args = self.mock_gh.update_issue_body.call_args_list[0][0]
294+
call2_args = self.mock_gh.update_issue_body.call_args_list[1][0]
295+
296+
self.assertEqual(call1_args[0], 123)
297+
self.assertIn("- [ ] #124", call1_args[1])
298+
self.assertIn("- [ ] Tag RC1", call1_args[1])
299+
self.assertIn(
300+
"- [x] Tag RC0 | status=done tag=2.0.0-rc0 commit=abcdef12\n- [ ]"
301+
" Tag RC1\n- [ ] Tag Final",
302+
call1_args[1].strip(),
303+
)
304+
305+
self.assertEqual(call2_args[0], 123)
306+
self.assertIn("- [x] #124 | status=done rc=rc1 commit= 12345678", call2_args[1])
307+
250308

251309
if __name__ == "__main__":
252310
unittest.main()

tools/private/release/process_backports.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from tools.private.release.release_issue import (
1111
RELEASE_TITLE_RE,
1212
add_backports_to_body,
13+
add_rc_task_to_body,
1314
parse_backports,
15+
parse_checklist_state,
1416
update_task_in_body,
1517
)
1618
from tools.private.release.utils import (
@@ -207,6 +209,19 @@ def _run_internal(self) -> int:
207209
print(f"Adding backports {args.add} to tracking issue #{args.issue}...")
208210
try:
209211
body = add_backports_to_body(body, args.add)
212+
state = parse_checklist_state(body)
213+
rc_tags = state.get("rc_tags", {})
214+
has_pending_rc = any(
215+
not task.checked and task.status != "done"
216+
for task in rc_tags.values()
217+
)
218+
next_rc_num = max(rc_tags.keys()) + 1 if rc_tags else 0
219+
if not has_pending_rc:
220+
print(
221+
f"No pending RC task found. Adding 'Tag"
222+
f" RC{next_rc_num}' to checklist..."
223+
)
224+
body = add_rc_task_to_body(body, next_rc_num)
210225
except ValueError as e:
211226
print(f"Error: {e}")
212227
return 1
@@ -219,6 +234,8 @@ def _run_internal(self) -> int:
219234
"[DRY RUN] Would update tracking issue checklist with new"
220235
" backports."
221236
)
237+
if not has_pending_rc:
238+
print(f"[DRY RUN] Would add 'Tag RC{next_rc_num}' to checklist.")
222239

223240
items = parse_backports(body)
224241

0 commit comments

Comments
 (0)