-
Notifications
You must be signed in to change notification settings - Fork 389
/
Copy pathrelease.sh
executable file
·300 lines (235 loc) · 10.5 KB
/
release.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#!/usr/bin/env bash
set -o nounset -o pipefail -o errexit
log_info() {
local BLUE='\033[0;34m'
local RESET='\033[0m'
printf -- "%b%b%b\n" "${BLUE}" "${*}" "${RESET}" 1>&2
}
log_success() {
local GREEN='\033[0;32m'
local RESET='\033[0m'
printf -- "%b%b%b\n" "${GREEN}" "${*}" "${RESET}" 1>&2
}
log_error() {
local RED='\033[0;31m'
local RESET='\033[0m'
printf -- "%b%b%b\n" "${RED}" "${*}" "${RESET}" 1>&2
exit 1
}
user_read_input() {
if [[ ${#} -lt 2 ]]; then
var_red "Usage: var_read_input VAR_PROMPT VAR_NAME"
return 1
fi
local VAR_PROMPT="${1}"
shift
local VAR_NAME="${1}"
shift
if [[ -n ${BASH_VERSION} ]]; then
read -r -p "${VAR_PROMPT}" "${@}" "${VAR_NAME}" </dev/tty
elif [[ -n ${ZSH_VERSION} ]]; then
read -r "${VAR_NAME}?${VAR_PROMPT}" "${@}" </dev/tty
else
var_error "Shell not supported for reading user input"
return 1
fi
}
user_confirm() {
local DEFAULT_PROMPT="[y/N]"
local DEFAULT_RETURN=1
if [[ ${2:-} == "true" ]] || [[ ${2:-} == "0" ]]; then
DEFAULT_RETURN=0
DEFAULT_PROMPT="[Y/n]"
fi
local input
user_read_input "${1:-Are you sure}? ${DEFAULT_PROMPT} " input
case "${input}" in
[yY][eE][sS] | [yY])
return 0
;;
[nN][oO] | [nN])
return 1
;;
*)
return ${DEFAULT_RETURN}
;;
esac
}
if [[ ${#} -ne 2 ]]; then
log_error "Usage: ${0} DESIRED_VERSION ACCOUNT[sandbox|prod|datadog]"
fi
if ! command -v jq >/dev/null 2>&1; then
log_error "jq not found, please install it following instructions here https://github.com/jqlang/jq#installation"
fi
if ! command -v yq >/dev/null 2>&1; then
log_error "yq not found, please install it following instructions here https://github.com/mikefarah/yq#install"
fi
if ! command -v hub >/dev/null 2>&1; then
log_error "hub not found, please install it following instructions here https://github.com/github/hub#installation"
fi
# Read the desired version
if [[ ! ${1} =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
log_error "You must use a semantic version (e.g. 3.1.4)"
else
FORWARDER_VERSION="${1}"
fi
# Check account parameter
VALID_ACCOUNTS=("sandbox" "prod" "datadog")
if [[ ! ${VALID_ACCOUNTS[@]} =~ ${2} ]]; then
log_error "The account parameter was invalid. Please choose sandbox, prod, or datadog"
fi
ACCOUNT="${2}"
if [[ ${ACCOUNT} == "prod" ]]; then
BUCKET="datadog-cloudformation-template"
elif [[ ${ACCOUNT} == "datadog" ]]; then
BUCKET="datadog-forwarder-cloudformation-template-org-2"
elif [[ ${ACCOUNT} == "sandbox" ]]; then
if [[ ${DEPLOY_TO_SERVERLESS_SANDBOX:-} == "true" ]]; then
BUCKET="datadog-cloudformation-template-serverless-sandbox"
else
BUCKET="datadog-cloudformation-template-test-sandbox"
fi
fi
# Read the current version
CURRENT_VERSION=$(yq '.Mappings.Constants.DdForwarder.Version' "template.yaml")
LAYER_NAME="Datadog-Forwarder"
BUNDLE_PATH=".forwarder/aws-dd-forwarder-${FORWARDER_VERSION}.zip"
aws_login() {
cfg=("$@")
shift
if [[ ${ACCOUNT} == "prod" ]]; then
aws-vault exec sso-prod-lambda-admin -- ${cfg[@]}
elif [[ ${ACCOUNT} == "datadog" ]]; then
aws-vault exec sso-prod-lambda-admin -- ${cfg[@]}
else
if [[ ${DEPLOY_TO_SERVERLESS_SANDBOX:-} == "true" ]]; then
aws-vault exec sso-serverless-sandbox-account-admin -- ${cfg[@]}
else
aws-vault exec sso-sandbox-account-admin -- ${cfg[@]}
fi
fi
}
get_max_layer_version() {
last_layer_version=$(aws_login aws lambda list-layer-versions --layer-name "${LAYER_NAME}" --region us-west-2 | jq -r ".LayerVersions | .[0] | .Version")
if [ "$last_layer_version" == "null" ]; then
echo 0
else
echo "${last_layer_version}"
fi
}
datadog_release() {
if ! user_confirm "Did you update the DdForwarder version and Layer in the template.yaml file before releasing"; then
log_error "Please update the Forwarder version in the template.yaml file"
fi
if [[ ! -e ${BUNDLE_PATH} ]] || ! user_confirm "Bundle already exists. Do you want to use it" "true"; then
log_info "Building the Forwarder bundle..."
./tools/build_bundle.sh "${FORWARDER_VERSION}"
fi
# Upload the bundle to S3 instead of GitHub for a org 2 release
log_info "Uploading a non-public version of Forwarder to S3..."
aws_login aws s3 cp "${BUNDLE_PATH}" "s3://${BUCKET}/aws/forwarder-zip/aws-dd-forwarder-${FORWARDER_VERSION}.zip"
# set urls
TEMPLATE_URL="https://${BUCKET}.s3.amazonaws.com/aws/forwarder/${FORWARDER_VERSION}.yaml"
FORWARDER_SOURCE_URL="s3://${BUCKET}/aws/forwarder-zip/aws-dd-forwarder-${FORWARDER_VERSION}.zip"
# don't publish layers we'll use the zip copier instead
}
sandbox_release() {
if [[ ! -e ${BUNDLE_PATH} ]] || ! user_confirm "Bundle already exists. Do you want to use it" "true"; then
log_info "Building the Forwarder bundle..."
./tools/build_bundle.sh "${FORWARDER_VERSION}"
log_info "Signing the Forwarder bundle..."
aws_login "./tools/sign_bundle.sh" "${BUNDLE_PATH}" "${ACCOUNT}"
fi
# Upload the bundle to S3 instead of GitHub for a sandbox release
log_info "Uploading non-public sandbox version of Forwarder to S3..."
aws_login aws s3 cp "${BUNDLE_PATH}" "s3://${BUCKET}/aws/forwarder-staging-zip/aws-dd-forwarder-${FORWARDER_VERSION}.zip"
# Upload the sandbox layers
log_info "Uploading layers"
./tools/publish_sandbox.sh "${LAYER_VERSION}" "${FORWARDER_VERSION}"
# Set vars for use in the installation test
TEMPLATE_URL="https://${BUCKET}.s3.amazonaws.com/aws/forwarder-staging/latest.yaml"
FORWARDER_SOURCE_URL="s3://${BUCKET}/aws/forwarder-staging-zip/aws-dd-forwarder-${FORWARDER_VERSION}.zip"
}
prod_release() {
if [[ ! $(./tools/semver.sh "${FORWARDER_VERSION}" "${CURRENT_VERSION}") > 0 ]]; then
log_error "Must use a version greater than the current ($CURRENT_VERSION)"
fi
# Make sure we are on the master branch
if [[ $(git rev-parse --abbrev-ref HEAD) != "master" ]]; then
log_error "Not on the master branch, aborting."
fi
log_info "You are about to\n\t- bump the version from ${CURRENT_VERSION} to ${FORWARDER_VERSION}\n\t- create lambda layer version ${LAYER_VERSION}\n\t- create a release of aws-dd-forwarder-${FORWARDER_VERSION} on GitHub\n\t- upload the template.yaml to s3://${BUCKET}/aws/forwarder/${FORWARDER_VERSION}.yaml\n"
# Confirm to proceed
if ! user_confirm "Continue"; then
log_error "Aborting..."
fi
# Get the latest code
git pull origin master
log_info "Bumping the version number to ${FORWARDER_VERSION}..."
perl -pi -e "s/DD_FORWARDER_VERSION = \"[0-9\.]+/DD_FORWARDER_VERSION = \"${FORWARDER_VERSION}/g" "settings.py"
# Update template.yaml
yq --inplace ".Mappings.Constants.DdForwarder.Version |= \"${FORWARDER_VERSION}\"" "template.yaml"
yq --inplace ".Mappings.Constants.DdForwarder.LayerVersion |= \"${LAYER_VERSION}\"" "template.yaml"
if ! git diff --quiet; then
log_info "Committing version number change..."
git add "settings.py" "template.yaml"
git commit --signoff --message "ci(release): Update version from ${CURRENT_VERSION} to ${FORWARDER_VERSION}"
fi
GIT_COMMIT="$(git rev-parse HEAD)"
log_info "Using ${GIT_COMMIT} commit as the release target..."
if [[ ! -e ${BUNDLE_PATH} ]] || ! user_confirm "Bundle already exists. Do you want to use it" "true"; then
log_info "Building the Forwarder bundle..."
./tools/build_bundle.sh "${FORWARDER_VERSION}"
log_info "Signing the Forwarder bundle..."
aws_login ./tools/sign_bundle.sh "${BUNDLE_PATH}" "${ACCOUNT}"
fi
log_info "Uploading layers..."
./tools/publish_prod.sh "${LAYER_VERSION}" "${FORWARDER_VERSION}"
log_info "Pushing version number change..."
git push origin master
# Create a GitHub release
log_info "Releasing aws-dd-forwarder-${FORWARDER_VERSION}, targetting commit ${GIT_COMMIT}, to GitHub..."
hub release create -a "${BUNDLE_PATH}" -m "aws-dd-forwarder-${FORWARDER_VERSION}" -t "${GIT_COMMIT}" "aws-dd-forwarder-${FORWARDER_VERSION}"
# Set vars for use in the installation test
TEMPLATE_URL="https://${BUCKET}.s3.amazonaws.com/aws/forwarder/latest.yaml"
FORWARDER_SOURCE_URL="https://github.com/DataDog/datadog-serverless-functions/releases/download/aws-dd-forwarder-${FORWARDER_VERSION}/aws-dd-forwarder-${FORWARDER_VERSION}.zip'"
}
# Validate identity
aws_login aws sts get-caller-identity
CURRENT_ACCOUNT="$(aws_login aws sts get-caller-identity --query Account --output text)"
CURRENT_LAYER_VERSION=$(get_max_layer_version)
LAYER_VERSION=$((CURRENT_LAYER_VERSION + 1))
if [[ ${ACCOUNT} != "datadog" ]]; then
log_info "Current layer version is ${CURRENT_LAYER_VERSION}, next layer version will be ${LAYER_VERSION}"
fi
log_info "Validating template.yaml..."
aws_login aws cloudformation validate-template --template-body "file://template.yaml"
if [[ ${ACCOUNT} == "prod" ]]; then
prod_release
elif [[ ${ACCOUNT} == "datadog" ]]; then
datadog_release
else
sandbox_release
fi
log_info "Uploading template.yaml to s3://${BUCKET}/aws/forwarder/${FORWARDER_VERSION}.yaml"
if [[ ${ACCOUNT} == "prod" ]]; then
aws_login aws s3 cp template.yaml "s3://${BUCKET}/aws/forwarder/${FORWARDER_VERSION}.yaml" \
--grants "read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
aws_login aws s3 cp template.yaml "s3://${BUCKET}/aws/forwarder/latest.yaml" \
--grants "read=uri=http://acs.amazonaws.com/groups/global/AllUsers"
elif [[ ${ACCOUNT} == "datadog" ]]; then
aws_login aws s3 cp template.yaml "s3://${BUCKET}/aws/forwarder/${FORWARDER_VERSION}.yaml"
aws_login aws s3 cp template.yaml "s3://${BUCKET}/aws/forwarder/latest.yaml"
else
aws_login aws s3 cp template.yaml "s3://${BUCKET}/aws/forwarder-staging/${FORWARDER_VERSION}.yaml"
aws_login aws s3 cp template.yaml "s3://${BUCKET}/aws/forwarder-staging/latest.yaml"
fi
log_success "Done uploading the CloudFormation template!"
log_info "Here is the CloudFormation quick launch URL:"
log_info "https://console.aws.amazon.com/cloudformation/home#/stacks/new?stackName=datadog-serverless&templateURL=${TEMPLATE_URL}"
log_success ""
log_success "Forwarder release process complete!"
if [[ ${ACCOUNT} == "prod" ]]; then
log_info "Don't forget to add release notes in GitHub!"
log_info "\thttps://github.com/DataDog/datadog-serverless-functions/releases"
fi