Skip to content

Commit 606b940

Browse files
Add script to merge master/main into PR branch
This script automates merging the master or main branch into a pull request branch when triggered by a specific comment on GitHub.
1 parent 5188da8 commit 606b940

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

merge_master.sh

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/bin/bash
2+
#
3+
# This script merges master (or main) into a PR branch when a PR comment contains
4+
# "merge master" or "merge main".
5+
#
6+
# It is meant to be triggered by a GitHub Action on `issue_comment.created`.
7+
8+
set -euo pipefail
9+
10+
# ----------- ENVIRONMENT CHECKS -----------
11+
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
12+
echo "Set the GITHUB_TOKEN env variable."
13+
exit 1
14+
fi
15+
16+
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
17+
echo "Set the GITHUB_REPOSITORY env variable."
18+
exit 1
19+
fi
20+
21+
if [[ -z "${GITHUB_EVENT_PATH:-}" ]]; then
22+
echo "Set the GITHUB_EVENT_PATH env variable."
23+
exit 1
24+
fi
25+
26+
# ----------- CONSTANTS -----------
27+
URI="https://api.github.com"
28+
API_HEADER="Accept: application/vnd.github.v3+json"
29+
AUTH_HEADER="Authorization: token ${GITHUB_TOKEN}"
30+
31+
# ----------- PARSE EVENT DATA -----------
32+
action=$(jq --raw-output .action "$GITHUB_EVENT_PATH")
33+
comment_body=$(jq --raw-output .comment.body "$GITHUB_EVENT_PATH" | tr -d '\r' | tr -d '\n' | xargs)
34+
issue_number=$(jq --raw-output .issue.number "$GITHUB_EVENT_PATH")
35+
36+
echo "Action: $action"
37+
echo "Comment: $comment_body"
38+
echo "PR Number: $issue_number"
39+
40+
# Only process new comments on PRs
41+
if [[ "$action" != "created" ]]; then
42+
echo "This script only runs for new comments."
43+
exit 0
44+
fi
45+
46+
is_pr=$(jq --raw-output '.issue.pull_request | if . != null then "true" else "false" end' "$GITHUB_EVENT_PATH")
47+
if [[ "$is_pr" != "true" ]]; then
48+
echo "Comment is not on a pull request."
49+
exit 0
50+
fi
51+
52+
# ----------- COMMAND CHECK -----------
53+
if [[ "$comment_body" != "merge master" && "$comment_body" != "merge main" ]]; then
54+
echo "No merge command found."
55+
exit 0
56+
fi
57+
58+
# ----------- FETCH PR DETAILS -----------
59+
echo "Fetching PR details..."
60+
pr_data=$(curl -sSL \
61+
-H "${AUTH_HEADER}" \
62+
-H "${API_HEADER}" \
63+
"${URI}/repos/${GITHUB_REPOSITORY}/pulls/${issue_number}")
64+
65+
head_ref=$(echo "$pr_data" | jq -r .head.ref)
66+
base_ref=$(echo "$pr_data" | jq -r .base.ref)
67+
68+
echo "Base branch: $base_ref"
69+
echo "PR branch: $head_ref"
70+
71+
# ----------- DETERMINE SOURCE BRANCH -----------
72+
merge_source="master"
73+
if [[ "$comment_body" == "merge main" ]]; then
74+
merge_source="main"
75+
fi
76+
77+
# ----------- CLONE AND MERGE -----------
78+
echo "Cloning repository and merging $merge_source into $head_ref..."
79+
git config --global user.name "github-actions[bot]"
80+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
81+
82+
git clone "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" repo
83+
cd repo
84+
85+
git fetch origin "$merge_source"
86+
git fetch origin "$head_ref"
87+
88+
git checkout "$head_ref"
89+
90+
# Attempt merge
91+
set +e
92+
git merge "origin/${merge_source}" --no-edit
93+
merge_exit=$?
94+
set -e
95+
96+
# ----------- HANDLE MERGE RESULT -----------
97+
if [[ $merge_exit -eq 0 ]]; then
98+
# Check if there’s anything to push
99+
if git diff --quiet HEAD "origin/${head_ref}"; then
100+
echo "No changes to push (branch already up to date)."
101+
curl -sSL \
102+
-H "${AUTH_HEADER}" \
103+
-H "${API_HEADER}" \
104+
-X POST \
105+
-d "{\"body\":\":information_source: ${merge_source} is already up to date with ${head_ref}.\"}" \
106+
"${URI}/repos/${GITHUB_REPOSITORY}/issues/${issue_number}/comments"
107+
exit 0
108+
fi
109+
110+
echo "Pushing merged branch..."
111+
git push origin "HEAD:${head_ref}"
112+
113+
# Comment success
114+
curl -sSL \
115+
-H "${AUTH_HEADER}" \
116+
-H "${API_HEADER}" \
117+
-X POST \
118+
-d "{\"body\":\":white_check_mark: Successfully merged ${merge_source} into ${head_ref}.\"}" \
119+
"${URI}/repos/${GITHUB_REPOSITORY}/issues/${issue_number}/comments"
120+
else
121+
echo "Merge conflict detected."
122+
curl -sSL \
123+
-H "${AUTH_HEADER}" \
124+
-H "${API_HEADER}" \
125+
-X POST \
126+
-d "{\"body\":\":x: Merge from ${merge_source} failed due to conflicts. Please resolve manually.\"}" \
127+
"${URI}/repos/${GITHUB_REPOSITORY}/issues/${issue_number}/comments"
128+
exit 1
129+
fi

0 commit comments

Comments
 (0)