public inbox for tools@linux.kernel.org
 help / color / mirror / Atom feed
* [PATCH b4 v2] Centralize b4 Message-ID policy
@ 2026-03-16 15:21 Tamir Duberstein
  2026-03-16 19:50 ` Konstantin Ryabitsev
  0 siblings, 1 reply; 2+ messages in thread
From: Tamir Duberstein @ 2026-03-16 15:21 UTC (permalink / raw)
  To: "Kernel.org Tools"; +Cc: Konstantin Ryabitsev, Tamir Duberstein

Route b4-owned Message-ID generation through b4.make_msgid()
with a default domain of b4 so stdlib never derives the
domain from the local hostname.

Commit 7ae850f409eb72ad25e55ea0fa283bfc5efa5492 did not
solve the problem because it only changed the review email
builder. TUI follow-up replies still went through
LoreMessage.make_reply(), which continued to call bare
email.utils.make_msgid() and therefore still produced
hostname-derived Message-IDs.

Signed-off-by: Tamir Duberstein <tamird@kernel.org>
Assisted-by: Codex gpt-5.4
---
Changes in v2:
- Use Assisted-by trailer.
- Link to v1: https://patch.msgid.link/20260316-review-reply-msgid-v1-1-7e3d5d377a69@kernel.org
---
 src/b4/__init__.py         |  7 ++++++-
 src/b4/ez.py               |  6 +++---
 src/b4/pr.py               |  5 ++++-
 src/b4/review/_review.py   |  6 +-----
 src/b4/ty.py               |  3 +--
 src/tests/test___init__.py | 14 ++++++++++++++
 src/tests/test_review.py   | 12 ------------
 7 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/src/b4/__init__.py b/src/b4/__init__.py
index 848b9d4..9b9f3df 100644
--- a/src/b4/__init__.py
+++ b/src/b4/__init__.py
@@ -2134,7 +2134,7 @@ class LoreMessage:
         references = LoreMessage.clean_header(self.msg.get('References', '') or '')
         msg['References'] = f'{references} <{self.msgid}>'.strip()
         msg['Date'] = email.utils.formatdate(localtime=True)
-        msg['Message-Id'] = email.utils.make_msgid()
+        msg['Message-Id'] = make_msgid(idstring='b4-reply')
         return msg
 
     @staticmethod
@@ -5048,6 +5048,11 @@ def get_mailfrom() -> Tuple[str, str]:
     return str(usercfg.get('name', '')), str(usercfg.get('email', ''))
 
 
+def make_msgid(idstring: Optional[str] = None, domain: str = 'b4') -> str:
+    """Wraps email.utils.make_msgid() to avoid hostname-derived message-ids."""
+    return email.utils.make_msgid(idstring=idstring, domain=domain)
+
+
 def is_maildir(dest: str) -> bool:
     return (os.path.isdir(os.path.join(dest, 'new'))
             and os.path.isdir(os.path.join(dest, 'cur'))
diff --git a/src/b4/ez.py b/src/b4/ez.py
index 87a6cfe..4bcb1ce 100644
--- a/src/b4/ez.py
+++ b/src/b4/ez.py
@@ -245,7 +245,7 @@ def auth_verify(cmdargs: argparse.Namespace) -> None:
     cmsg = EmailMessage()
     cmsg.add_header('From', myemail)
     cmsg.add_header('Subject', 'b4-send-verify')
-    cmsg.add_header('Message-ID', email.utils.make_msgid(domain='b4'))
+    cmsg.add_header('Message-ID', b4.make_msgid())
     cmsg.set_charset('utf-8')
     cmsg.set_payload(f'verify:{vstr}\n', charset='utf-8')
     bdata = cmsg.as_bytes(policy=b4.emlpolicy)
@@ -1186,7 +1186,7 @@ def update_trailers(cmdargs: argparse.Namespace) -> None:
         if cover:
             cmsg = EmailMessage()
             cmsg['Subject'] = f'[PATCH 0/{len(patches)}] cover'
-            cmsg['Message-Id'] = email.utils.make_msgid(domain='b4')
+            cmsg['Message-Id'] = b4.make_msgid()
             cmsg.set_payload('cover', 'us-ascii')
             patches.insert(0, ('', cmsg))
             rethread(patches)
@@ -2924,7 +2924,7 @@ def auto_to_cc() -> None:
     if extras:
         # Make it a LoreMessage, so we can run a fix_trailers on it
         cmsg = EmailMessage()
-        cmsg['Message-ID'] = email.utils.make_msgid(domain='b4')
+        cmsg['Message-ID'] = b4.make_msgid()
         cmsg['Subject'] = 'Cover letter'
         cmsg.set_payload(cover, charset='utf-8')
         clm = b4.LoreMessage(cmsg)
diff --git a/src/b4/pr.py b/src/b4/pr.py
index ea74c32..5969a0d 100644
--- a/src/b4/pr.py
+++ b/src/b4/pr.py
@@ -392,7 +392,10 @@ def get_pr_from_github(ghurl: str) -> Optional[b4.LoreMessage]:
     msg['From'] = f'{uname} <{uemail}>'
     title = prdata.get('title', '')
     msg['Subject'] = f'[GIT PULL] {title}'
-    msg['Message-Id'] = utils.make_msgid(idstring=f'{rproj}-{rrepo}-pr-{rpull}', domain='github.com')
+    msg['Message-Id'] = b4.make_msgid(
+        idstring=f'{rproj}-{rrepo}-pr-{rpull}',
+        domain='github.com',
+    )
     created_at = utils.format_datetime(datetime.strptime(prdata.get('created_at'), '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc))
     msg['Date'] = created_at
     msg.set_charset('utf-8')
diff --git a/src/b4/review/_review.py b/src/b4/review/_review.py
index f4937b5..5b026a5 100644
--- a/src/b4/review/_review.py
+++ b/src/b4/review/_review.py
@@ -2359,11 +2359,7 @@ def _build_review_email(series: Dict[str, Any], patch_meta: Optional[Dict[str, A
     else:
         msg['References'] = f'<{header_info["msgid"]}>'
     msg['Date'] = email.utils.formatdate(localtime=True)
-    _, _, mid_domain = user_email.rpartition('@')
-    msg['Message-Id'] = email.utils.make_msgid(
-        idstring='b4-review',
-        domain=mid_domain or 'b4',
-    )
+    msg['Message-Id'] = b4.make_msgid(idstring='b4-review')
 
     return msg
 
diff --git a/src/b4/ty.py b/src/b4/ty.py
index 098e241..533d0a4 100644
--- a/src/b4/ty.py
+++ b/src/b4/ty.py
@@ -118,8 +118,7 @@ def make_reply(reply_template: str, jsondata: JsonDictT, gitdir: Optional[str],
     else:
         msg.add_header('Subject', 'Re: ' + subject)
 
-    mydomain = jsondata['myemail'].split('@')[1]
-    msg['Message-Id'] = email.utils.make_msgid(idstring='b4-ty', domain=mydomain)
+    msg['Message-Id'] = b4.make_msgid(idstring='b4-ty')
     msg['Date'] = email.utils.formatdate(localtime=True)
     body = Template(reply_template).safe_substitute(jsondata)
     msg.set_payload(body, charset='utf-8')
diff --git a/src/tests/test___init__.py b/src/tests/test___init__.py
index 64ad2f9..6275ece 100644
--- a/src/tests/test___init__.py
+++ b/src/tests/test___init__.py
@@ -5,6 +5,7 @@ import email
 import email.parser
 import io
 import pathlib
+import socket
 
 from typing import Any, Dict, List, Literal, Optional, Tuple
 
@@ -58,6 +59,19 @@ def test_save_git_am_mbox(sampledir: Optional[str], tmp_path: pathlib.Path, sour
     assert re.search(regex, res, flags=flags)
 
 
+def _msgid_domain(msgid: str) -> str:
+    return msgid.strip('<>').rsplit('@', maxsplit=1)[1]
+
+
+def test_make_msgid_avoids_host_domain_by_default() -> None:
+    stdlib_msgid = email.utils.make_msgid()
+    b4_msgid = b4.make_msgid(idstring='b4-test')
+
+    assert _msgid_domain(stdlib_msgid) == socket.getfqdn()
+    assert _msgid_domain(b4_msgid) == 'b4'
+    assert _msgid_domain(b4_msgid) != socket.getfqdn()
+
+
 @pytest.mark.parametrize('source,expected', [
     ('trailers-test-simple',
      [('person', 'Reported-by', '"Doe, Jane" <jane@example.com>', None),
diff --git a/src/tests/test_review.py b/src/tests/test_review.py
index f15b906..ffffb87 100644
--- a/src/tests/test_review.py
+++ b/src/tests/test_review.py
@@ -1302,18 +1302,6 @@ class TestBuildReviewEmailHeaders:
         assert 'reviewer@example.com' in msg['From']
         assert 'Reviewer' in msg['From']
 
-    @mock.patch('b4.get_email_signature', return_value='sig')
-    @mock.patch('b4.get_user_config', return_value={
-        'name': 'Reviewer', 'email': 'reviewer@example.com'})
-    def test_message_id_uses_reviewer_domain(self, _mock_cfg: mock.Mock,
-                                             _mock_sig: mock.Mock) -> None:
-        msg = review._build_review_email(
-            self._make_series(), None, self._make_review(), 'cover', '', None)
-        assert msg is not None
-        assert msg['Message-Id'].endswith('@example.com>')
-        assert '.ip6.arpa' not in msg['Message-Id']
-
-
 # -- Tests for _build_review_email() user-edited To/Cc -----------------------
 
 class TestBuildReviewEmailToCcEdited:

---
base-commit: ada9a7554864c5c21944f3d098c04862c54e3e7c
change-id: 20260316-review-reply-msgid-b2d72bb77f4b

Best regards,
--  
Tamir Duberstein <tamird@kernel.org>


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH b4 v2] Centralize b4 Message-ID policy
  2026-03-16 15:21 [PATCH b4 v2] Centralize b4 Message-ID policy Tamir Duberstein
@ 2026-03-16 19:50 ` Konstantin Ryabitsev
  0 siblings, 0 replies; 2+ messages in thread
From: Konstantin Ryabitsev @ 2026-03-16 19:50 UTC (permalink / raw)
  To: Kernel.org Tools, Tamir Duberstein


On Mon, 16 Mar 2026 11:21:55 -0400, Tamir Duberstein wrote:
> Centralize b4 Message-ID policy

Applied, thanks!

[1/1] Centralize b4 Message-ID policy
      https://git.kernel.org/pub/scm/utils/b4/b4.git/commit/?id=4520fe6cfb7c

Best regards,
-- 
KR



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-03-16 19:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16 15:21 [PATCH b4 v2] Centralize b4 Message-ID policy Tamir Duberstein
2026-03-16 19:50 ` Konstantin Ryabitsev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox