Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions merge-upstream-pull-request.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env bash
source ~/.discordauth

# ~/.discordauth contains:
# CHANNELID=x
# TOKEN=x
# CHANNELID being the Discord Channel ID
# TOKEN being the bot token

set -u # don't expand unbound variable
set -f # disable pathname expansion
set -C # noclobber

readonly BASE_BRANCH_NAME="upstream-merge-"
readonly BASE_PULL_URL="https://api.github.com/repos/tgstation/tgstation/pulls"

# Ensure the current directory is a git directory
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi

# Ensure all given parameters exist
if [ $# -eq 0 ]; then
echo "Error: No arguments have been given, the first argument needs to be a pull ID, the second argument needs to be the commit message"
exit 1
fi

# Ensure curl exists and is available in the current context
type curl >/dev/null 2>&1 || { echo >&2 "Error: This script requires curl, please ensure curl is installed and exists in the current PATH"; exit 1; }

# Ensure jq exists and is available in the current context
type jq >/dev/null 2>&1 || { echo >&2 "Error: This script requires jq, please ensure jq is installed and exists in the current PATH"; exit 1; }

containsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}

# Make sure we have our upstream remote
if ! git remote | grep tgstation > /dev/null; then
git remote add tgstation https://github.com/tgstation/tgstation.git
fi

curl -v \
-H "Authorization: Bot $TOKEN" \
-H "User-Agent: myBotThing (http://some.url, v0.1)" \
-H "Content-Type: application/json" \
-X POST \
-d "{\"content\":\"Mirroring [$1] from /tg/ to Hippie\"}" \
https://discordapp.com/api/channels/$CHANNELID/messages

# We need to make sure we are always on a clean master when creating the new branch.
# So we forcefully reset, clean and then checkout the master branch
git fetch --all
git checkout master
git reset --hard origin/master
git clean -f

# Remove the other branches
git branch | grep -v "master" | xargs git branch -D

# Create a new branch
git checkout -b "$BASE_BRANCH_NAME$1"

# Grab the SHA of the merge commit
readonly MERGE_SHA=$(curl --silent "$BASE_PULL_URL/$1" | jq '.merge_commit_sha' -r)

# Get the commits
readonly COMMITS=$(curl "$BASE_PULL_URL/$1/commits" | jq '.[].sha' -r)

# Cherry pick onto the new branch
CHERRY_PICK_OUTPUT=$(git cherry-pick -m 1 "$MERGE_SHA" 2>&1)
echo "$CHERRY_PICK_OUTPUT"

# If it's a squash commit, you can't use -m 1, you need to remove it
# You also can't use -m 1 if it's a rebase and merge...
if echo "$CHERRY_PICK_OUTPUT" | grep 'error: mainline was specified but commit'; then
echo "Commit was a squash, retrying"
if containsElement "$MERGE_SHA" "${COMMITS[@]}"; then
for commit in $COMMITS; do
echo "Cherry-picking: $commit"
git cherry-pick "$commit"
# Add all files onto this branch
git add -A .
git cherry-pick --continue
done
else
echo "Cherry-picking: $MERGE_SHA"
git cherry-pick "$MERGE_SHA"
# Add all files onto this branch
git add -A .
git cherry-pick --continue
fi

else
# Add all files onto this branch
git add -A .
fi

# Commit these changes
git commit --allow-empty -m "$2"

# Push them onto the branch
git push -u origin "$BASE_BRANCH_NAME$1"