Skip to content

Commit e6c44c8

Browse files
authored
always automatically update pr branch before merging (#351)
1 parent 9fe50dd commit e6c44c8

File tree

1 file changed

+54
-9
lines changed

1 file changed

+54
-9
lines changed

script/merge.clj

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,66 @@
4646
(println "Found PR: " (pr-str pr-to-merge))
4747
(:number pr-to-merge)))
4848

49+
(defn update-pr-branch
50+
"Update the PR branch to include latest changes from base branch, resolving conflicts by taking incoming changes"
51+
[{:keys [dry-run? pr-number head-ref-name]}]
52+
(ice/p [:blue "Updating PR branch to latest master..."])
53+
(if-not dry-run?
54+
;; First try the API approach (clean merge)
55+
(let [{:keys [exit]} (p/sh "gh" "api"
56+
"--method" "PUT"
57+
(str "/repos/metabase/docs.metabase.github.io/pulls/" pr-number "/update-branch"))]
58+
(if (zero? exit)
59+
(ice/p [:green "✓ PR branch updated successfully via API"])
60+
(do
61+
(ice/p [:yellow "API update failed, likely due to conflict, trying git-based resolution..."])
62+
;; If API fails due to conflicts, resolve manually
63+
(try
64+
;; Fetch latest and checkout the PR branch
65+
(p/sh "git" "fetch" "origin")
66+
(p/sh "git" "checkout" head-ref-name)
67+
(prn (p/sh "git" "status"))
68+
69+
;; Try to merge master - this will show conflicts
70+
(let [merge-result (p/shell {:continue true} "git" "merge" "origin/master")]
71+
(if (= 0 (:exit merge-result))
72+
(ice/p [:green "✓ Clean merge successful"])
73+
(do
74+
;; Resolve conflicts by taking all changes from The PR Branch
75+
(ice/p [:blue "Resolving conflicts by preferring our changes..."])
76+
(p/sh "git" "checkout" "--ours" ".")
77+
(p/sh "git" "add" ".")
78+
(p/sh "git" "commit" "--no-edit" "-m" (str "Merge master, preferring changes from PR #" pr-number))
79+
(ice/p [:green "✓ Conflicts resolved, preferring PR branch's changes"]))))
80+
81+
;; Push the updated branch
82+
(p/sh "git" "push" "origin" head-ref-name)
83+
(ice/p [:green "✓ PR branch updated via git"])
84+
85+
(catch Exception git-e
86+
(ice/p [:red "Git-based update also failed: " (.getMessage git-e)]))))))
87+
(println "Dry run mode: would update PR branch, resolving conflicts by preferring incoming changes")))
88+
89+
(defn- gh-pr-merge [dry-run? pr-number]
90+
(let [cmd ["gh" "pr" "merge" pr-number "--squash" "--delete-branch"]]
91+
(if dry-run?
92+
(ice/p [:yellow "Dry run mode: not actually merging PR:\n"
93+
[:white [:bold "Would run: "] [:underline (str/join " " cmd)]]])
94+
(apply p/sh cmd))))
95+
4996
(defn -main [& args]
5097
(let [{:keys [source-branch target-branch]
5198
dry-run? :dry-run
5299
:as opts} (cli/parse-opts args cli-spec)
53100
pr-number (source+target-branch->pr-number source-branch target-branch)]
54-
(if-not pr-number
101+
(when-not pr-number
55102
(throw (ex-info (ice/p-str [:red "No PR found for source branch "] [:bold source-branch] " and target branch " [:bold target-branch] ".")
56-
{:babashka/exit 1 :opts opts}))
57-
(do
58-
(ice/p [:green "Merging PR for branch "] [:bold source-branch] " into " [:bold target-branch] " with PR number " [:bold (pr-str pr-number)])
59-
(if-not dry-run?
60-
(p/sh "gh" "pr" "merge" pr-number "--squash" "--delete-branch")
61-
(do
62-
(println "Dry run mode: not actually merging PR")
63-
(println "Would run: gh pr merge" pr-number "--squash --delete-branch")))))))
103+
{:babashka/exit 1 :opts opts})))
104+
(update-pr-branch {:dry-run? dry-run?
105+
:pr-number pr-number
106+
:head-ref-name (str source-branch "->" target-branch)})
107+
(ice/p [:green "Merging PR for branch "] [:bold source-branch] " into " [:bold target-branch] " with PR number " [:bold (pr-str pr-number)])
108+
(gh-pr-merge dry-run? pr-number)))
64109

65110
(when (= *file* (System/getProperty "babashka.file"))
66111
(apply -main *command-line-args*))

0 commit comments

Comments
 (0)