-
Notifications
You must be signed in to change notification settings - Fork 2
/
git-promote
executable file
·115 lines (96 loc) · 3.37 KB
/
git-promote
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash
if [ "$#" -lt 2 ] || [ "$1" = "-h" ]; then
echo "usage: git promote <tag> <release-branch>"
exit
fi
PRERELEASE_TAG=$1
TARGET_BRANCH=$2
INDEX=`expr index "$PRERELEASE_TAG" -`
RELEASE_TAG=${PRERELEASE_TAG:0:INDEX-1}
CURRENT_BRANCH="$(git symbolic-ref --short HEAD)"
WORKING_DIRECTORY=$(pwd)
STASH_OUTPUT=''
check_for_release_tag(){
TAG_EXISTS="$(git ls-remote --exit-code --tags origin $RELEASE_TAG)"
if [ $? = 0 ]; then
echo "ERROR: "
echo "Release tag $RELEASE_TAG already exists in remote repository origin"
exit 11
fi
}
unstash_changes() {
if [ "$STASH_OUTPUT" != "No local changes to save" ]; then
echo "Attempting to unstash local changes"
POP_STASH="$(git stash pop)"
if [ $? != 0 ]; then
echo "ERROR:"
echo "$POP_STASH"
exit 9
fi
fi
}
restore_original_state()
{
echo "Attempting to return to branch $CURRENT_BRANCH"
CLEAR_INDEX="$(git reset --hard HEAD)"
if [ $? != 0 ]; then
echo "ERROR:"
echo "$CLEAR_INDEX"
fi
CHECKOUT_ORIGINAL_OUTPUT="$(git checkout -q $CURRENT_BRANCH)"
if [ $? != 0 ]; then
echo "ERROR:"
echo "$CHECKOUT_ORIGINAL_OUTPUT"
exit 8
fi
unstash_changes
cd $WORKING_DIRECTORY
}
run_command()
{
output="$($1 2>&1)"
if [ $? != 0 ]; then
printf "ERROR: %s\n" "$output"
return 1
else
return 0
fi
}
echo "Attempting to securely promote prerelease $PRERELEASE_TAG into 'origin/$TARGET_BRANCH' with tag $RELEASE_TAG"
check_for_release_tag
echo "Stashing any local changes and checking out remote branch 'origin/$TARGET_BRANCH'"
STASH_OUTPUT="$(git -c commit.gpgSign=false stash save -a)" || exit 1;
cd $(git rev-parse --show-toplevel)
echo "Securely fetching remote branches and tags."
echo " Fetching $PRERELEASE_TAG..."
echo " Signing RSL fetch entry for $PRERELEASE_TAG..."
echo " <---- GPG signature required"
run_command "git secure-fetch $PRERELEASE_TAG" || { unstash_changes && exit 2; }
echo " Fetching $TARGET_BRANCH..."
echo " Signing RSL fetch entry for $TARGET_BRANCH..."
echo " <---- GPG signature required"
run_command "git secure-fetch $TARGET_BRANCH" || { unstash_changes && exit 2; }
echo "Checking out $TARGET_BRANCH"
run_command "git checkout $TARGET_BRANCH" || { unstash_changes && exit 3; }
echo "Fast-forward latest changes"
run_command "git merge --ff-only origin/$TARGET_BRANCH" || { restore_original_state && exit 4; }
echo "Fast forward successful!"
echo "Merging tagged version $PRERELEASE_TAG into $TARGET_BRANCH"
echo " Signing merge commit."
echo " <---- GPG authentication required."
run_command "git merge -S --no-ff $PRERELEASE_TAG" || { restore_original_state && exit 5; }
echo "Merge successful!"
echo "Tagging HEAD with $RELEASE_TAG"
echo " Signing tag object."
echo " <---- GPG authentication required."
run_command "git tag -s $RELEASE_TAG -m $RELEASE_TAG" || { restore_original_state && exit 6; }
echo "Attempting to push to remote repository 'origin'"
echo " Clearsigning RSL push entry and signing RSL commit for branch $TARGET_BRANCH"
echo " <---- 2 GPG signatures required"
run_command "git secure-push origin $TARGET_BRANCH" || { restore_original_state && exit 7; }
echo " Clearsigning RSL push entry and signing RSL commit for tag $RELEASE_TAG"
echo " <---- 2 GPG signatures required"
run_command "git secure-push origin $RELEASE_TAG" || { restore_original_state && exit 7; }
echo "Push Successful!"
restore_original_state
exit 0