From: Christian Brauner <brauner@kernel.org>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: "Christian Brauner (Amutable)" <brauner@kernel.org>,
Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Subject: [PATCH b4 06/27] review: don't let archiving a series raise
Date: Fri, 31 Jul 2026 11:21:05 +0200 [thread overview]
Message-ID: <20260731-work-b4-editor-branch-guard-v1-6-de68a7c8e4cb@kernel.org> (raw)
In-Reply-To: <20260731-work-b4-editor-branch-guard-v1-0-de68a7c8e4cb@kernel.org>
archive_series() builds a tarball and writes it into the data directory
without guarding any of it, so ENOSPC, a permission problem or a missing
object comes back to the caller as an exception.
Both callers archive a series that has just been thanked, the tracking
UI right after the SMTP handoff and queue delivery right after the
message goes out. The mail is gone by then. An exception unwinding
through the send path is reported as a failure to send, which tells the
maintainer to send a note that is already on the list, or it escapes the
screen callback and takes the rest of the TUI session with it.
Report the write failure as (False, detail) like every other failure
here. Nothing has been destroyed at that point so the archive can be
retried. Do the same for the Patchwork update, except that it comes
last. The local archive is done and can't be retried, so a Patchwork
hiccup is a warning and not a failed archive.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
src/b4/review/_review.py | 70 ++++++++++++++++++++++++++++--------------------
1 file changed, 41 insertions(+), 29 deletions(-)
diff --git a/src/b4/review/_review.py b/src/b4/review/_review.py
index da20fc4..4c67387 100644
--- a/src/b4/review/_review.py
+++ b/src/b4/review/_review.py
@@ -809,6 +809,8 @@ def archive_series(
Returns (success, detail): detail is the archive tarball path on
success (empty for a database-only archive), or an error message.
+ Never raises: callers archive *after* a thank-you has gone out, and a
+ failure here must not be mistaken for a failure to deliver it.
"""
# Imported here: the tarball machinery is only needed when archiving.
# b4.review.tracking is re-imported alongside b4.ez because a local
@@ -833,36 +835,40 @@ def archive_series(
if not first_patch:
return False, 'No patch commits found in tracking data'
- tio = io.BytesIO()
- mnow = int(time.time())
- with tarfile.open(fileobj=tio, mode='w:gz') as tfh:
- # Add cover letter
- ifh = io.BytesIO()
- ifh.write(cover_text.encode())
- b4.ez.write_to_tar(tfh, f'{change_id}/cover.txt', mnow, ifh)
- ifh.close()
- # Add tracking metadata
- ifh = io.BytesIO()
- ifh.write(make_review_magic_json(tracking).encode())
- b4.ez.write_to_tar(tfh, f'{change_id}/tracking.js', mnow, ifh)
- ifh.close()
- # Add patches as mbox
- patches = b4.git_range_to_patches(
- topdir, f'{first_patch}~1', f'{review_branch}~1'
- )
- if patches:
+ try:
+ tio = io.BytesIO()
+ mnow = int(time.time())
+ with tarfile.open(fileobj=tio, mode='w:gz') as tfh:
+ # Add cover letter
ifh = io.BytesIO()
- b4.save_git_am_mbox([patch[1] for patch in patches], ifh)
- b4.ez.write_to_tar(tfh, f'{change_id}/patches.mbx', mnow, ifh)
+ ifh.write(cover_text.encode())
+ b4.ez.write_to_tar(tfh, f'{change_id}/cover.txt', mnow, ifh)
ifh.close()
+ # Add tracking metadata
+ ifh = io.BytesIO()
+ ifh.write(make_review_magic_json(tracking).encode())
+ b4.ez.write_to_tar(tfh, f'{change_id}/tracking.js', mnow, ifh)
+ ifh.close()
+ # Add patches as mbox
+ patches = b4.git_range_to_patches(
+ topdir, f'{first_patch}~1', f'{review_branch}~1'
+ )
+ if patches:
+ ifh = io.BytesIO()
+ b4.save_git_am_mbox([patch[1] for patch in patches], ifh)
+ b4.ez.write_to_tar(tfh, f'{change_id}/patches.mbx', mnow, ifh)
+ ifh.close()
- # Write archive to data directory
- datadir = b4.get_data_dir()
- archpath = os.path.join(datadir, 'review-archived')
- os.makedirs(archpath, exist_ok=True)
- tarpath = os.path.join(archpath, f'{change_id}.tar.gz')
- with open(tarpath, mode='wb') as tout:
- tout.write(tio.getvalue())
+ # Write archive to data directory
+ datadir = b4.get_data_dir()
+ archpath = os.path.join(datadir, 'review-archived')
+ os.makedirs(archpath, exist_ok=True)
+ tarpath = os.path.join(archpath, f'{change_id}.tar.gz')
+ with open(tarpath, mode='wb') as tout:
+ tout.write(tio.getvalue())
+ except Exception as ex:
+ # The branch is still intact, so this is safe to retry
+ return False, f'Could not write archive for {change_id}: {ex}'
ok, err = delete_review_branch(topdir, review_branch, allow_switch=allow_switch)
if not ok:
@@ -878,9 +884,15 @@ def archive_series(
except Exception as ex:
return False, f'DB error: {ex}'
- # Mark as archived in Patchwork
+ # Mark as archived in Patchwork. The local archive is already done and
+ # cannot be retried, so a Patchwork hiccup is a warning, not a failure.
if pw_series_id:
- pw_update_series_state(pw_series_id, 'accepted', archived=True)
+ try:
+ pw_update_series_state(pw_series_id, 'accepted', archived=True)
+ except Exception as ex:
+ logger.warning(
+ 'Could not archive series %s in Patchwork: %s', change_id, ex
+ )
return True, tarpath
--
2.53.0
next prev parent reply other threads:[~2026-07-31 9:21 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 9:20 [PATCH b4 00/27] Stop the editor branch guard from eating review replies Christian Brauner
2026-07-31 9:21 ` [PATCH b4 01/27] review-tui: mark all outgoing mail as read, not just " Christian Brauner
2026-07-31 9:21 ` [PATCH b4 02/27] tests: cover the shared outgoing-seen helper Christian Brauner
2026-07-31 9:21 ` [PATCH b4 03/27] review: close the messages database when auto-marking fails Christian Brauner
2026-07-31 9:21 ` [PATCH b4 04/27] review: use the same busy timeout for both review databases Christian Brauner
2026-07-31 9:21 ` [PATCH b4 05/27] review: drop the unused return value from set_flags_bulk() Christian Brauner
2026-07-31 9:21 ` Christian Brauner [this message]
2026-07-31 9:21 ` [PATCH b4 07/27] tests: cover an unwritable series archive Christian Brauner
2026-07-31 9:21 ` [PATCH b4 08/27] review-tui: keep post-send bookkeeping out of the send error path Christian Brauner
2026-07-31 9:21 ` [PATCH b4 09/27] tests: cover the thank-you send's post-send bookkeeping Christian Brauner
2026-07-31 9:21 ` [PATCH b4 10/27] review-tui: say when a take didn't complete Christian Brauner
2026-07-31 9:21 ` [PATCH b4 11/27] tests: cover the unaccepted take in the thank-and-archive chain Christian Brauner
2026-07-31 9:21 ` [PATCH b4 12/27] review-tui: use the shared helper to delete a review branch Christian Brauner
2026-07-31 9:21 ` [PATCH b4 13/27] ty: check reachability in the repository the commit landed in Christian Brauner
2026-07-31 9:21 ` [PATCH b4 14/27] tests: cover the publish check using the repository it is given Christian Brauner
2026-07-31 9:21 ` [PATCH b4 15/27] edit_in_editor: make the branch guard opt-in Christian Brauner
2026-07-31 9:21 ` [PATCH b4 16/27] tests: cover the opt-in branch guard in edit_in_editor Christian Brauner
2026-07-31 9:21 ` [PATCH b4 17/27] edit_in_editor: work in the tree the caller names Christian Brauner
2026-07-31 9:21 ` [PATCH b4 18/27] tests: cover edit_in_editor working in the caller's tree Christian Brauner
2026-07-31 9:21 ` [PATCH b4 19/27] tui: route editor launches through one non-fatal helper Christian Brauner
2026-07-31 9:21 ` [PATCH b4 20/27] tests: cover an editor failure leaving the review TUI standing Christian Brauner
2026-07-31 9:21 ` [PATCH b4 21/27] review-tui: only put back a branch b4 checked out itself Christian Brauner
2026-07-31 9:21 ` [PATCH b4 22/27] tests: cover the review TUI's branch-restore guard Christian Brauner
2026-07-31 9:21 ` [PATCH b4 23/27] tests: pin the default branch in the queue-delivery fixture Christian Brauner
2026-07-31 9:21 ` [PATCH b4 24/27] ty: an unknown remote tip is undetermined, not unpublished Christian Brauner
2026-07-31 9:21 ` [PATCH b4 25/27] review-tui: keep post-send bookkeeping out of the review send error path Christian Brauner
2026-07-31 9:21 ` [PATCH b4 26/27] tests: cover the review send's post-send bookkeeping Christian Brauner
2026-07-31 9:21 ` [PATCH b4 27/27] review: close the tracking database when archiving fails Christian Brauner
2026-07-31 13:14 ` [PATCH b4 00/27] Stop the editor branch guard from eating review replies Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260731-work-b4-editor-branch-guard-v1-6-de68a7c8e4cb@kernel.org \
--to=brauner@kernel.org \
--cc=konstantin@linuxfoundation.org \
--cc=tools@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox