-
-
Notifications
You must be signed in to change notification settings - Fork 275
/
Copy pathpre-deploy.sh
executable file
·156 lines (128 loc) · 4.18 KB
/
pre-deploy.sh
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env bash
#
# Description
# ===========
#
# Pre-deploy hook. Does the following:
# 1. Shows the commits about to be pushed
# 2. Ask for confirmation (exit with 1 if not confirming)
# 3. Notify Slack
#
#
# Developing
# ==========
#
# During development, the best way to test it is to call the script
# directly with `./scripts/pre-deploy.sh staging|production`. You can also set
# the `SLACK_CHANNEL` to your personnal channel so you don't flood the team.
# To do that, right click on your own name in Slack, `Copy link`, then
# only keep the last part of the URL.
#
# Or you can set `PUSH_TO_SLACK` to false to echo the payload instead of
# sending it.
#
# ------------------------------------------------------------------------------
if [ "$#" -ne 1 ]; then
echo "Usage: [DEPLOY_MSG='An optional custom deploy message'] $0 staging|production"
exit 1
fi
# ---- Variables ----
if [ "$1" == "staging" ]; then
DEPLOY_ORIGIN_URL="https://git.heroku.com/opencollective-staging-api.git"
elif [ "$1" == "production" ]; then
DEPLOY_ORIGIN_URL="https://git.heroku.com/opencollective-prod-api.git"
else
echo "Unknwown remote $1"
exit 1
fi
PUSH_TO_SLACK=true # Setting this to false will echo the message instead of pushing to Slack
SLACK_CHANNEL="CEZUS9WH3"
LOCAL_ORIGIN="origin"
PRE_DEPLOY_ORIGIN="predeploy-${1}"
LOCAL_BRANCH="main"
PRE_DEPLOY_BRANCH="main"
GIT_LOG_FORMAT_SHELL='short'
GIT_LOG_FORMAT_SLACK='format:<https://github.com/opencollective/opencollective-api/commit/%H|[%ci]> *%an* %n_%<(80,trunc)%s_%n'
GIT_LOG_COMPARISON="$PRE_DEPLOY_ORIGIN/$PRE_DEPLOY_BRANCH..$LOCAL_ORIGIN/$LOCAL_BRANCH"
# ---- Utils ----
function confirm()
{
echo -n "$@"
read -e answer
for response in y Y yes YES Yes Sure sure SURE OK ok Ok
do
if [ "$answer" == "$response" ]
then
return 0
fi
done
# Any answer other than the list above is considerred a "no" answer
return 1
}
function exit_success()
{
echo "🚀 Deploying now..."
exit 0
}
# ---- Ensure we have a reference to the remote ----
git remote add $PRE_DEPLOY_ORIGIN $DEPLOY_ORIGIN_URL &> /dev/null
# ---- Show the commits about to be pushed ----
# Update deploy remote
echo "ℹ️ Fetching remote $1 state..."
git fetch $PRE_DEPLOY_ORIGIN > /dev/null
echo ""
echo "-------------- New commits --------------"
git --no-pager log --pretty="${GIT_LOG_FORMAT_SHELL}" $GIT_LOG_COMPARISON
echo "-----------------------------------------"
echo ""
# ---- Ask for confirmation ----
echo "ℹ️ You're about to deploy the preceding commits from main branch to $1 server."
confirm "❔ Are you sure (yes/no) > " || exit 1
# ---- Slack notification ----
cd -- "$(dirname $0)/.."
eval $(cat .env | grep OC_SLACK_DEPLOY_WEBHOOK=)
if [ -z "$OC_SLACK_DEPLOY_WEBHOOK" ]; then
# Emit a warning as we don't want the deploy to crash just because we
# havn't setup a Slack token. Get yours on https://api.slack.com/custom-integrations/legacy-tokens
echo "ℹ️ OC_SLACK_DEPLOY_WEBHOOK is not set, I will not notify Slack about this deploy 😞 (please do it manually)"
exit_success
fi
ESCAPED_CHANGELOG=$(
git log --pretty="${GIT_LOG_FORMAT_SLACK}" $GIT_LOG_COMPARISON \
| sed 's/"/\\\\"/g'
)
if [ ! -z "$DEPLOY_MSG" ]; then
CUSTOM_MESSAGE="-- _$(echo $DEPLOY_MSG | sed 's/"/\\\\"/g' | sed "s/'/\\\\'/g")_"
fi
read -d '' PAYLOAD << EOF
{
"channel": "${SLACK_CHANNEL}",
"text": ":unicorn_face: Deploying *API* to *${1}* ($(git config user.name)) ${CUSTOM_MESSAGE}",
"as_user": true,
"attachments": [{
"text": "
---------------------------------------------------------------------------------------------------
${ESCAPED_CHANGELOG}
"
}]
}
EOF
if [ $PUSH_TO_SLACK = "true" ]; then
curl \
-H "Content-Type: application/json; charset=utf-8" \
-d "$PAYLOAD" \
-s \
--fail \
"$OC_SLACK_DEPLOY_WEBHOOK" \
&> /dev/null
if [ $? -ne 0 ]; then
echo "⚠️ I won't be able to notify slack. Please do it manually and check your OC_SLACK_DEPLOY_WEBHOOK"
else
echo "🔔 Slack notified about this deployment."
fi
else
echo "Following message would be posted on Slack:"
echo "$PAYLOAD"
fi
# Always exit with 0 to continue the deploy even if slack notification failed
exit_success