@scriptdb/cli 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,376 @@
1
+ #!/usr/bin/env bash
2
+
3
+ #
4
+ # deploy(1) - Minimalistic shell script to deploy Git repositories.
5
+ # Released under the MIT License.
6
+ #
7
+ # https://github.com/visionmedia/deploy
8
+ #
9
+
10
+ VERSION="0.6.0"
11
+ CONFIG=./deploy.conf
12
+ LOG=/tmp/pm2-deploy-${USER:-default}.log
13
+ FORCE=0
14
+ REF=
15
+ ENV=
16
+
17
+ #
18
+ # Read PIPED JSON
19
+ #
20
+ read conf
21
+
22
+ #
23
+ # Output usage information.
24
+ #
25
+
26
+ usage() {
27
+ cat <<-EOF
28
+
29
+ Usage: deploy [options] <env> [command]
30
+
31
+ Options:
32
+
33
+ -C, --chdir <path> change the working directory to <path>
34
+ -c, --config <path> set config path. defaults to ./deploy.conf
35
+ -V, --version output program version
36
+ -h, --help output help information
37
+ -f, --force skip local change checking
38
+
39
+ Commands:
40
+
41
+ setup run remote setup commands
42
+ revert [n] revert to [n]th last deployment or 1
43
+ config [key] output config file or [key]
44
+ curr[ent] output current release commit
45
+ prev[ious] output previous release commit
46
+ exec|run <cmd> execute the given <cmd>
47
+ list list previous deploy commits
48
+ ref [ref] deploy [ref]
49
+
50
+ EOF
51
+ }
52
+
53
+ #
54
+ # Abort with <msg>
55
+ #
56
+
57
+ abort() {
58
+ echo
59
+ echo " $@" 1>&2
60
+ echo
61
+ exit 1
62
+ }
63
+
64
+ #
65
+ # Log <msg>.
66
+ #
67
+
68
+ log() {
69
+ echo " ○ $@"
70
+ }
71
+
72
+ #
73
+ # Get config value by <key>.
74
+ #
75
+
76
+ config_get() {
77
+ local key=$1
78
+ echo $(expr "$conf" : '.*"'$key'":"\([^"]*\)"')
79
+ }
80
+
81
+ #
82
+ # Output version.
83
+ #
84
+
85
+ version() {
86
+ echo $VERSION
87
+ }
88
+
89
+ #
90
+ # Return the ssh command to run.
91
+ #
92
+
93
+ ssh_command() {
94
+ local user="`config_get user`"
95
+ if test -n "$user"; then
96
+ local url="$user@`config_get host`"
97
+ else
98
+ local url="`config_get host`"
99
+ fi
100
+ local unexpanded_key="`config_get key`"
101
+ local key="${unexpanded_key/#\~/$HOME}"
102
+ local forward_agent="`config_get forward-agent`"
103
+ local port="`config_get port`"
104
+ local needs_tty="`config_get needs_tty`"
105
+ local ssh_options="`config_get ssh_options`"
106
+
107
+ test -n "$forward_agent" && local agent="-A"
108
+ test -n "$key" && local identity="-i $key"
109
+ test -n "$port" && local port="-p $port"
110
+ test -n "$needs_tty" && local tty="-t"
111
+ test -n "ssh_options" && local ssh_opts="$ssh_options"
112
+ echo "ssh $ssh_opts $tty $agent $port $identity $url"
113
+ }
114
+
115
+ #
116
+ # Run the given remote <cmd>.
117
+ #
118
+
119
+ runRemote() {
120
+ local shell="`ssh_command`"
121
+ echo $shell "\"$@\"" >> $LOG
122
+ $shell $@
123
+ }
124
+
125
+ #
126
+ # Run the given local <cmd>.
127
+ #
128
+
129
+ runLocal() {
130
+ echo "\"$@\"" >> $LOG
131
+ /usr/bin/env bash -c "$*"
132
+ }
133
+
134
+ #
135
+ # Run the given <cmd> either locally or remotely
136
+ #
137
+
138
+ run() {
139
+ local host="`config_get host`"
140
+ if [[ $host == localhost ]]
141
+ then
142
+ runLocal $@
143
+ else
144
+ runRemote $@
145
+ fi
146
+ }
147
+
148
+ #
149
+ # Output config or [key].
150
+ #
151
+
152
+ config() {
153
+ echo $(expr "$conf" : '.*"$key":"\([^"]*\)"')
154
+ }
155
+
156
+ #
157
+ # Execute hook <name> relative to the path configured.
158
+ #
159
+
160
+ hook() {
161
+ test -n "$1" || abort hook name required
162
+ local hook=$1
163
+ local path=`config_get path`
164
+ local cmd=`config_get $hook`
165
+ if test -n "$cmd"; then
166
+ log "executing $hook \`$cmd\`"
167
+ run "cd $path/current; \
168
+ SHARED=\"$path/shared\" \
169
+ $cmd 2>&1 | tee -a $LOG; \
170
+ exit \${PIPESTATUS[0]}"
171
+ test $? -eq 0
172
+ else
173
+ log hook $hook
174
+ fi
175
+ }
176
+
177
+ #
178
+ # Pre Setup hook runs on the host before the actual setup runs
179
+ # multiple commands or a script
180
+ #
181
+
182
+ hook_pre_setup() {
183
+ local cmd=`config_get pre-setup`
184
+ if test -n "$cmd"; then
185
+ local is_script=($cmd)
186
+ if [ -f "${is_script[0]}" ]; then
187
+ log "executing pre-setup script \`$cmd\`"
188
+ local shell="`ssh_command`"
189
+ runLocal "$shell 'bash -s' -- < $cmd"
190
+ else
191
+ log "executing pre-setup \`$cmd\`"
192
+ run "$cmd"
193
+ fi
194
+ test $? -eq 0
195
+ else
196
+ log hook pre-setup
197
+ fi
198
+ }
199
+
200
+ #
201
+ # Run setup.
202
+ #
203
+
204
+ setup() {
205
+ local path=`config_get path`
206
+ local repo=`config_get repo`
207
+ local ref=`config_get ref`
208
+ local fetch=`config_get fetch`
209
+ local branch=${ref#*/}
210
+
211
+ hook_pre_setup || abort pre-setup hook failed
212
+ run "mkdir -p $path/{shared/{logs,pids},source}"
213
+ test $? -eq 0 || abort setup paths failed
214
+ log running setup
215
+ log cloning $repo
216
+ if test "$fetch" != "fast"; then
217
+ log "full fetch"
218
+ run "git clone --branch $branch $repo $path/source"
219
+ else
220
+ log "fast fetch"
221
+ run "git clone --depth=5 --branch $branch $repo $path/source"
222
+ fi
223
+ test $? -eq 0 || abort failed to clone
224
+ run "ln -sfn $path/source $path/current"
225
+ test $? -eq 0 || abort symlink failed
226
+ hook post-setup || abort post-setup hook failed
227
+ log setup complete
228
+ }
229
+
230
+ #
231
+ # Deploy [ref].
232
+ #
233
+
234
+ deploy() {
235
+ local ref=$1
236
+ local branch=$2
237
+
238
+ if test -z "$branch"; then
239
+ branch=${ref#*/}
240
+ fi
241
+ local path=`config_get path`
242
+ local fetch=`config_get fetch`
243
+
244
+ log "deploying ${ref}"
245
+
246
+ # 1- Execute local commands
247
+ log executing pre-deploy-local
248
+ local pdl=`config_get pre-deploy-local`
249
+ runLocal $pdl || abort pre-deploy-local hook failed
250
+
251
+ # 2- Execute pre deploy commands on remote server
252
+ hook pre-deploy || abort pre-deploy hook failed
253
+
254
+ # 3- Fetch updates
255
+ log fetching updates
256
+ if test "$fetch" != "fast"; then
257
+ log "full fetch"
258
+ run "cd $path/source && git fetch --all --tags"
259
+ else
260
+ log "fast fetch"
261
+ run "cd $path/source && git fetch --depth=5 --all --tags"
262
+ fi
263
+ test $? -eq 0 || abort fetch failed
264
+
265
+ # 4- If no reference retrieve shorthand name for the remote repo
266
+ if test -z "$ref"; then
267
+ log fetching latest tag
268
+ ref=`run "cd $path/source && git for-each-ref \
269
+ --sort=-*authordate \
270
+ --format='%(refname)' \
271
+ --count=1 | cut -d '/' -f 3"`
272
+ test $? -eq 0 || abort failed to determine latest tag
273
+ fi
274
+
275
+ # 5- Reset to ref
276
+ log resetting HEAD to $ref
277
+ run "cd $path/source && git reset --hard $ref"
278
+ test $? -eq 0 || abort git reset failed
279
+
280
+ # 6- Link current
281
+ run "ln -sfn $path/source $path/current"
282
+ test $? -eq 0 || abort symlink failed
283
+
284
+ # deploy log
285
+ run "cd $path/source && \
286
+ echo \`git rev-parse HEAD\` \
287
+ >> $path/.deploys"
288
+ test $? -eq 0 || abort deploy log append failed
289
+
290
+ hook post-deploy || abort post-deploy hook failed
291
+
292
+ # done
293
+ log successfully deployed $ref
294
+ }
295
+
296
+ #
297
+ # Get current commit.
298
+ #
299
+
300
+ current_commit() {
301
+ local path=`config_get path`
302
+ run "cd $path/source && \
303
+ git rev-parse --short HEAD"
304
+ }
305
+
306
+ #
307
+ # Get <n>th deploy commit.
308
+ #
309
+
310
+ nth_deploy_commit() {
311
+ local n=$1
312
+ local path=`config_get path`
313
+ run "cat $path/.deploys | tail -n $n | head -n 1 | cut -d ' ' -f 1"
314
+ }
315
+
316
+ #
317
+ # List deploys.
318
+ #
319
+
320
+ list_deploys() {
321
+ local path=`config_get path`
322
+ run "tac $path/.deploys | awk '{printf \"%d\t%s\n\", NR-1, \$0}'"
323
+ }
324
+
325
+ #
326
+ # Revert to the <n>th last deployment.
327
+ #
328
+
329
+ revert_to() {
330
+ local n=$1
331
+ log "reverting $n deploy(s)"
332
+ local commit=`nth_deploy_commit $((n + 1))`
333
+ deploy "$commit"
334
+ }
335
+
336
+ #
337
+ # Ensure all changes are committed and pushed before deploying.
338
+ #
339
+
340
+ check_for_local_changes() {
341
+ local path=`config_get path`
342
+
343
+ if [ $FORCE -eq 1 ]
344
+ then
345
+ return
346
+ fi
347
+ git --no-pager diff --exit-code --quiet || abort "commit or stash your changes before deploying"
348
+ git --no-pager diff --exit-code --quiet --cached || abort "commit your staged changes before deploying"
349
+ [ -z "`git rev-list @{upstream}.. -n 1`" ] || abort "push your changes before deploying"
350
+ }
351
+
352
+ # parse argv
353
+ while test $# -ne 0; do
354
+ arg=$1; shift
355
+ case $arg in
356
+ -h|--help) usage; exit ;;
357
+ -V|--version) version; exit ;;
358
+ -C|--chdir) log cd $1; cd $1; shift ;;
359
+ -F|--force) FORCE=1 ;;
360
+ run|exec) run "cd `config_get path`/current && $@"; exit ;;
361
+ console) console; exit ;;
362
+ curr|current) current_commit; exit ;;
363
+ prev|previous) nth_deploy_commit 2; exit ;;
364
+ revert) revert_to ${1-1}; exit ;;
365
+ setup) setup $@; exit ;;
366
+ list) list_deploys; exit ;;
367
+ config) config $@; exit ;;
368
+ ref) REF=$1; BRANCH=$2 ;;
369
+ esac
370
+ done
371
+
372
+ check_for_local_changes
373
+
374
+ echo
375
+ # deploy
376
+ deploy "${REF:-`config_get ref`}" "${BRANCH}"