-
Notifications
You must be signed in to change notification settings - Fork 1
/
make.sh
executable file
·295 lines (244 loc) · 7.87 KB
/
make.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
#!/bin/bash
log() { echo -e "\e[30;47m ${1} \e[0m ${@:2}"; } # $1 background white
info() { echo -e "\e[48;5;28m ${1} \e[0m ${@:2}"; } # $1 background green
warn() { echo -e "\e[48;5;202m ${1} \e[0m ${@:2}" >&2; } # $1 background orange
error() { echo -e "\e[48;5;196m ${1} \e[0m ${@:2}" >&2; } # $1 background red
# the directory containing the script file
export PROJECT_DIR="$(cd "$(dirname "$0")"; pwd)"
#
# variables
#
[[ -f $PROJECT_DIR/.env ]] \
&& source $PROJECT_DIR/.env \
|| warn WARN .env file is missing
#
# overwrite TF variables
#
export TF_VAR_project_name=$PROJECT_NAME
export TF_VAR_service_name=$SERVICE_NAME
export TF_VAR_region=$AWS_REGION
# log $1 in underline then $@ then a newline
under() {
local arg=$1
shift
echo -e "\033[0;4m${arg}\033[0m ${@}"
echo
}
usage() {
under usage 'call the Makefile directly: make dev
or invoke this file directly: ./make.sh dev'
}
env-create() {
local PROJECT_NAME=applicationset
# setup .env file with default values
scripts/env-file.sh .env \
AWS_PROFILE=default \
PROJECT_NAME=$PROJECT_NAME \
SERVICE_NAME=as-convert \
APP_NAME=convert \
CONVERT_PORT=4000
# setup .env file again
# /!\ use your own values /!\
scripts/env-file.sh .env \
AWS_REGION=eu-west-3
}
terraform-init() {
export CHDIR="$PROJECT_DIR/terraform"
scripts/terraform-init.sh
scripts/terraform-validate.sh
}
# terraform create ecr repo + setup .env file
terraform-create() {
export CHDIR="$PROJECT_DIR/terraform"
scripts/terraform-validate.sh
scripts/terraform-apply.sh
}
convert() {
cd "$PROJECT_DIR/$APP_NAME"
npm install
NODE_ENV=development \
CONVERT_PORT=$CONVERT_PORT \
DEBUG=$APP_NAME npx nodemon index.js
}
test() {
log CONVERT_PORT $CONVERT_PORT
curl http://localhost:$CONVERT_PORT/greyscale \
--form "file=@test/rhino.jpg" \
--silent \
--output rhino.jpg
# must be rhino.jpg JPEG
identify rhino.jpg
curl http://localhost:$CONVERT_PORT/greyscale \
--form "file=@test/rhino.png" \
--silent \
--output rhino.png
# must be rhino.png PNG
identify rhino.png
curl http://localhost:$CONVERT_PORT/greyscale \
--form "file=@test/rhino.webp" \
--silent \
--output rhino.webp
# must be rhino.webp WEBP
identify rhino.webp
# must be HTTP/1.1 400 Bad Request
curl http://localhost:$CONVERT_PORT/greyscale \
--silent \
--dump-header - \
--form "file=@test/rhino.bmp" \
| grep HTTP.*400 \
--extended-regexp \
--color=none
# must be Invalid format
curl http://localhost:$CONVERT_PORT/greyscale \
--form "file=@test/rhino.bmp" \
--silent
echo
}
dev-build() {
cd "$PROJECT_DIR/$APP_NAME"
docker image build \
--file Dockerfile.dev \
--tag $APP_NAME-dev \
.
docker images \
--filter="reference=$APP_NAME-dev" \
--filter="reference=$APP_NAME" \
--filter="reference=$REPOSITORY_URL"
}
dev-run() {
log CONVERT_PORT $CONVERT_PORT
docker run \
--rm \
--env-file .env \
--env NODE_ENV=development \
--publish $CONVERT_PORT:$CONVERT_PORT \
--name $APP_NAME-dev \
$APP_NAME-dev
}
dev-stop() {
docker rm --force $APP_NAME-dev 2>/dev/null
}
prod-build() {
# --file Dockerfile \
cd "$PROJECT_DIR/$APP_NAME"
docker image build \
--tag $APP_NAME \
.
docker images \
--filter="reference=$APP_NAME-dev" \
--filter="reference=$APP_NAME" \
--filter="reference=$REPOSITORY_URL"
}
prod-run() {
log CONVERT_PORT $CONVERT_PORT
docker run \
--rm \
--env-file .env \
--publish $CONVERT_PORT:$CONVERT_PORT \
--name $APP_NAME \
$APP_NAME
}
prod-stop() {
docker rm --force $APP_NAME 2>/dev/null
}
update-patch() {
log APP_NAME $APP_NAME
VERSION=$(jq --raw-output '.version' $APP_NAME/package.json)
log VERSION $VERSION
UPDATED=$(semver-cli inc patch $VERSION)
log UPDATED $UPDATED
# https://stackoverflow.com/a/68136589
# output redirection produces empty file with jq
# needed to store in $UPDATED variable before write
PACKAGE=$(jq ".version = \"$UPDATED\"" $APP_NAME/package.json)
echo "$PACKAGE" > $APP_NAME/package.json
info UPDATE $APP_NAME/package.json version to $(jq .version --raw-output $APP_NAME/package.json)
}
# push convert image to ecr
ecr-push() {
info MAKE prod-build
prod-build
cd "$PROJECT_DIR"
log AWS_ACCOUNT_ID $AWS_ACCOUNT_ID
log AWS_REGION $AWS_REGION
log REPOSITORY_URL $REPOSITORY_URL
# add login data into /home/$USER/.docker/config.json (create or update authorization token)
aws ecr get-login-password \
--region $AWS_REGION \
--profile $AWS_PROFILE \
| docker login \
--username AWS \
--password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
# https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt---shortlength
# default length is 7
SHORT_SHA=$(git rev-parse --short=9 HEAD)
log SHORT_SHA $SHORT_SHA
VERSION=$(jq --raw-output '.version' $APP_NAME/package.json)
log VERSION $VERSION
# https://docs.docker.com/engine/reference/commandline/tag/
docker tag $APP_NAME $REPOSITORY_URL:$SHORT_SHA
docker tag $APP_NAME $REPOSITORY_URL:$VERSION
docker tag $APP_NAME $REPOSITORY_URL:latest
# https://docs.docker.com/engine/reference/commandline/push/
docker push $REPOSITORY_URL:$SHORT_SHA
docker push $REPOSITORY_URL:$VERSION
docker push $REPOSITORY_URL:latest
}
# run latest image pushed to ecr
ecr-run() {
log APP_NAME $APP_NAME
log AWS_ACCOUNT_ID $AWS_ACCOUNT_ID
log AWS_REGION $AWS_REGION
log REPOSITORY_URL $REPOSITORY_URL
log CONVERT_PORT $CONVERT_PORT
# add login data into /home/$USER/.docker/config.json (create or update authorization token)
aws ecr get-login-password \
--region $AWS_REGION \
--profile $AWS_PROFILE \
| docker login \
--username AWS \
--password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
docker run \
--rm \
--env-file .env \
--publish $CONVERT_PORT:$CONVERT_PORT \
--name $APP_NAME \
$REPOSITORY_URL:latest
}
increase-build-push() {
info MAKE update-patch
update-patch
info MAKE ecr-push
ecr-push
}
# terraform destroy ecr repo + setup .env file
terraform-destroy() {
terraform -chdir=$PROJECT_DIR/terraform destroy -auto-approve
}
# clear docker images
clear() {
log REPOSITORY_URL $REPOSITORY_URL
# https://stackoverflow.com/a/58821333/1503073
# remove all tags from an image
# https://stackoverflow.com/a/8296746/1503073
# ignore xargs commands if stdin input is empty
# if `docker images --filter` return nothing, `xargs docker rmi`` throw
# an error : "docker rmi" requires at least 1 argument.
# xargs option
# -r, --no-run-if-empty : if the standard input does not contain any nonblanks, do not run the command.
docker images --filter="reference=$APP_NAME" --format='{{.ID}}' \
| xargs --no-run-if-empty docker rmi --force
docker images --filter="reference=$APP_NAME-dev" --format='{{.ID}}' \
| xargs --no-run-if-empty docker rmi --force
docker images --filter="reference=$REPOSITORY_URL" --format='{{.ID}}' \
| xargs --no-run-if-empty docker rmi --force
# https://docs.docker.com/engine/reference/commandline/image_prune/
# remove unused images
docker image prune --force
}
# if `$1` is a function, execute it. Otherwise, print usage
# compgen -A 'function' list all declared functions
# https://stackoverflow.com/a/2627461
FUNC=$(compgen -A 'function' | grep $1)
[[ -n $FUNC ]] && { info EXECUTE $1; eval $1; } || usage;
exit 0