This is an automated email from the ASF dual-hosted git repository.

Yicong-Huang pushed a commit to branch release/v1.1.0-incubating
in repository https://gitbox.apache.org/repos/asf/texera.git


The following commit(s) were added to refs/heads/release/v1.1.0-incubating by 
this push:
     new 12315e67c3 fix(ci): place "(backported from commit X)" before trailers 
in backport message (#4696)
12315e67c3 is described below

commit 12315e67c339a6f36f147d86b7633453a3bacb1b
Author: Yicong Huang <[email protected]>
AuthorDate: Sat May 2 23:39:39 2026 -0700

    fix(ci): place "(backported from commit X)" before trailers in backport 
message (#4696)
    
    ### What changes were proposed in this PR?
    
    Direct backports currently append the `(backported from commit X)` note
    at the very end of the commit message. Because GitHub's squash-merge
    messages already carry a trailer block (`Co-Authored-By:` etc.) at the
    end, the note ends up *after* the trailers:
    
    ```
    fix: foo
    
    Body.
    
    Closes #123.
    
    Co-Authored-By: Claude Opus 4.7 <[email protected]>
    
    (backported from commit abc1234)        ← currently here
    ```
    
    Git treats the trailer block as the contiguous run of `Key: value` lines
    at the very end of the message, separated from the body by a blank line.
    With a non-trailer line trailing the trailer block, `git
    interpret-trailers --parse` sees zero trailers — tools that read
    Co-Authored-By, Signed-off-by, etc. lose the metadata for backport
    commits.
    
    This PR re-orders the composition so the body comes first, then the
    `(backported from commit X)` note as its own paragraph, then the trailer
    block at the very end:
    
    ```
    fix: foo
    
    Body.
    
    Closes #123.
    
    (backported from commit abc1234)        ← moved here
    
    Co-Authored-By: Claude Opus 4.7 <[email protected]>
    ```
    
    A small Python step inside the workflow splits the original message at
    the trailer boundary using the standard `^[A-Za-z][A-Za-z0-9-]*:\s`
    heuristic and reassembles. Cases handled:
    
    | input | output |
    |---|---|
    | body + trailers | body + blank + note + blank + trailers |
    | body, no trailers | body + blank + note |
    | multiple trailers | body + blank + note + blank + all trailers
    contiguous |
    
    ### Any related issues, documentation, discussions?
    
    None — incidental fix to the backport job alongside the broader CI
    cleanup work.
    
    ### How was this PR tested?
    
    Ran the assembled Python step locally against five synthetic message
    shapes:
    
    | input | result |
    |---|---|
    | subject only (`docs: typo fix`) | subject + blank + note |
    | subject + body, no trailers | subject + body + blank + note |
    | subject + body + single trailer | subject + body + blank + note +
    blank + trailer |
    | subject + body + multiple trailers | subject + body + blank + note +
    blank + all trailers contiguous |
    | body containing a non-trailer `Word:` line | subject + body + blank +
    note (body line not mis-classified) |
    
    The last case is the trailer-detection tightening: a trailer block
    exists only when there is a blank line in the message AND every line
    after the last blank line is in trailer format. That avoids treating a
    Conventional Commits subject (`feat: foo` for a one-line commit) as a
    one-line trailer block.
    
    The next direct-backport CI run on this branch's merge will exercise the
    path end-to-end.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.7, 1M context)
    
    ---------
    
    (backported from commit a5b895715e589f7f74c1459cd314861288126532)
    
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
 .github/workflows/direct-backport-push.yml | 46 ++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/direct-backport-push.yml 
b/.github/workflows/direct-backport-push.yml
index c9fc6b20a1..215a888996 100644
--- a/.github/workflows/direct-backport-push.yml
+++ b/.github/workflows/direct-backport-push.yml
@@ -221,8 +221,48 @@ jobs:
           git checkout -B "${TARGET_BRANCH}" "origin/${TARGET_BRANCH}"
           git cherry-pick --no-commit "${MERGE_SHA}"
 
-          {
-            printf '%s\n\n(backported from commit %s)\n' "${merge_message}" 
"${MERGE_SHA}"
-          } | git commit -F - --author="${original_author}"
+          # Compose the final commit message. The "(backported from commit X)"
+          # note goes between the message body and the trailer block (the
+          # trailing run of `Key: value` lines such as Co-Authored-By and
+          # Signed-off-by) so trailers stay contiguous at the bottom of the
+          # message — that's where git itself parses them.
+          #
+          # The trailer block, by git convention, is the run of `Key: value`
+          # lines after the LAST blank line in the message, and only counts
+          # if EVERY line after that blank line is in trailer format. This
+          # avoids mis-detecting a Conventional Commits subject like
+          # "feat: foo" or a body line like "References:" as a trailer.
+          new_message=$(
+            printf '%s' "${merge_message}" | \
+              python3 -c '
+import re, sys
+sha = sys.argv[1]
+msg = sys.stdin.read().rstrip("\n")
+lines = msg.split("\n")
+trailer_re = re.compile(r"^[A-Za-z][A-Za-z0-9-]*:\s")
+
+last_blank = -1
+for idx in range(len(lines) - 1, -1, -1):
+    if lines[idx] == "":
+        last_blank = idx
+        break
+
+trailer_start = len(lines)
+if last_blank != -1:
+    candidate = lines[last_blank + 1:]
+    if candidate and all(trailer_re.match(l) for l in candidate):
+        trailer_start = last_blank + 1
+
+backport = f"(backported from commit {sha})"
+if trailer_start == len(lines):
+    print(msg + "\n\n" + backport)
+else:
+    body = "\n".join(lines[:trailer_start]).rstrip("\n")
+    trailers = "\n".join(lines[trailer_start:])
+    print(body + "\n\n" + backport + "\n\n" + trailers)
+' "${MERGE_SHA}"
+          )
+
+          printf '%s\n' "${new_message}" | git commit -F - 
--author="${original_author}"
 
           git push origin "HEAD:${TARGET_BRANCH}"

Reply via email to