From 1d44d0102a28121bf8143ea5024e7e340bb0dd91 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Sat, 28 Dec 2024 20:41:11 -0500 Subject: [PATCH] test(repo sync): verify squash-merge behavior (#535) Adds a test that squash-merges a shamhub PR and verifies that repo sync behaves as expected. --- internal/forge/shamhub/cli.go | 2 + internal/forge/shamhub/merge.go | 29 ++++-- testdata/script/repo_sync_squash_merged.txt | 99 +++++++++++++++++++++ 3 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 testdata/script/repo_sync_squash_merged.txt diff --git a/internal/forge/shamhub/cli.go b/internal/forge/shamhub/cli.go index 571e10af..29503b21 100644 --- a/internal/forge/shamhub/cli.go +++ b/internal/forge/shamhub/cli.go @@ -136,6 +136,7 @@ func (c *Cmd) Run(ts *testscript.TestScript, neg bool, args []string) { } prune := flag.Bool("prune", false, "prune the branch after merging") + squash := flag.Bool("squash", false, "squash-merge the commit") ts.Check(flag.Parse(args)) args = flag.Args() if len(args) != 2 { @@ -158,6 +159,7 @@ func (c *Cmd) Run(ts *testscript.TestScript, neg bool, args []string) { Repo: repo, Number: pr, DeleteBranch: *prune, + Squash: *squash, } if at := ts.Getenv("GIT_COMMITTER_DATE"); at != "" { t, err := time.Parse(time.RFC3339, at) diff --git a/internal/forge/shamhub/merge.go b/internal/forge/shamhub/merge.go index 4ef69f6b..d73e8b9c 100644 --- a/internal/forge/shamhub/merge.go +++ b/internal/forge/shamhub/merge.go @@ -105,7 +105,10 @@ type MergeChangeRequest struct { // should be deleted after the merge. DeleteBranch bool - // TODO: option to use squash commit + // Squash requests that the CR be merged + // as a single squashed commit with the PR subject/body + // instead of a merge commit. + Squash bool } // MergeChange merges an open change against this forge. @@ -180,14 +183,22 @@ func (sh *ShamHub) MergeChange(req MergeChangeRequest) error { logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel) defer flush() - msg := fmt.Sprintf("Merge change #%d", req.Number) - cmd := exec.Command(sh.gitExe, - "commit-tree", - "-p", sh.changes[changeIdx].Base, - "-p", sh.changes[changeIdx].Head, - "-m", msg, - tree, - ) + change := sh.changes[changeIdx] + + var msg string + args := []string{"commit-tree", "-p", change.Base} + if req.Squash { + msg = fmt.Sprintf("%s (#%d)\n\n%s", + change.Subject, + req.Number, + change.Body) + } else { + msg = fmt.Sprintf("Merge change #%d", req.Number) + args = append(args, "-p", change.Head) + } + args = append(args, "-m", msg, tree) + + cmd := exec.Command(sh.gitExe, args...) cmd.Dir = sh.repoDir(req.Owner, req.Repo) cmd.Stderr = logw cmd.Env = append(os.Environ(), commitEnv...) diff --git a/testdata/script/repo_sync_squash_merged.txt b/testdata/script/repo_sync_squash_merged.txt new file mode 100644 index 00000000..ebc2cb15 --- /dev/null +++ b/testdata/script/repo_sync_squash_merged.txt @@ -0,0 +1,99 @@ +# 'repo sync' handles squash-merged CRs correctly. + +as 'Test ' +at '2024-12-28T18:14:15Z' + +# setup +cd repo +git init +git commit --allow-empty -m 'Initial commit' + +# set up a fake GitHub remote +shamhub init +shamhub new origin alice/example.git +shamhub register alice +git push origin main + +env SHAMHUB_USERNAME=alice +gs auth login + +# put all three changes in one commit +git add feat1.txt +gs bc -m 'Add feature 1' +git add feat2.txt +gs cc -m 'Add feature 2' +git add feat3.txt +gs cc -m 'Add feature 3' + +# Submit +env ROBOT_INPUT=$WORK/robot.golden ROBOT_OUTPUT=$WORK/robot.actual +gs branch submit +cmp $WORK/robot.actual $WORK/robot.golden +stderr 'Created #' + +shamhub dump change 1 +cmpenvJSON stdout $WORK/golden/pull.txt + +gs ll +cmp stderr $WORK/golden/ll-before.txt + +shamhub merge --squash --prune alice/example 1 +gs repo sync +stderr '#1 was merged' + +git log -n1 --pretty=%B +cmp stdout $WORK/golden/final-commit-msg + +gs ll +cmp stderr $WORK/golden/ll-after.txt + +-- repo/feat1.txt -- +feature 1 +-- repo/feat2.txt -- +feature 2 +-- repo/feat3.txt -- +feature 3 + +-- robot.golden -- +=== +> Title: Add feature 1 +> Short summary of the change +"Add multiple features" +=== +> Body: Press [e] to open mockedit or [enter/tab] to skip +> Open your editor to write a detailed description of the change +{"give": "Adds features 1, 2, and 3 in one PR."} +=== +> Draft: [y/N] +> Mark the change as a draft? +false +-- golden/pull.txt -- +{ + "number": 1, + "html_url": "$SHAMHUB_URL/alice/example/change/1", + "state": "open", + "title": "Add multiple features", + "body": "Adds features 1, 2, and 3 in one PR.", + "base": { + "ref": "main", + "sha": "e41b284d1e80e3acba627274a80d94129ebdf8fd" + }, + "head": { + "ref": "add-feature-1", + "sha": "a9548da1d2feba06f2bba402eb77adf27a9266e7" + } +} + +-- golden/ll-before.txt -- +┏━■ add-feature-1 (#1) ◀ +┃ a9548da Add feature 3 (now) +┃ bcb3a72 Add feature 2 (now) +┃ 4be7a61 Add feature 1 (now) +main +-- golden/ll-after.txt -- +main ◀ +-- golden/final-commit-msg -- +Add multiple features (#1) + +Adds features 1, 2, and 3 in one PR. +