|
46 | 46 | (println "Found PR: " (pr-str pr-to-merge))
|
47 | 47 | (:number pr-to-merge)))
|
48 | 48 |
|
| 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 | + |
49 | 96 | (defn -main [& args]
|
50 | 97 | (let [{:keys [source-branch target-branch]
|
51 | 98 | dry-run? :dry-run
|
52 | 99 | :as opts} (cli/parse-opts args cli-spec)
|
53 | 100 | pr-number (source+target-branch->pr-number source-branch target-branch)]
|
54 |
| - (if-not pr-number |
| 101 | + (when-not pr-number |
55 | 102 | (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))) |
64 | 109 |
|
65 | 110 | (when (= *file* (System/getProperty "babashka.file"))
|
66 | 111 | (apply -main *command-line-args*))
|
0 commit comments