Skip to content
This repository was archived by the owner on Dec 11, 2018. It is now read-only.

Commit 7548e18

Browse files
committed
Deploy stuff
1 parent eb027d3 commit 7548e18

File tree

2 files changed

+354
-0
lines changed

2 files changed

+354
-0
lines changed

deploy

+346
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
#!/usr/bin/env bash
2+
3+
VERSION="0.4.0"
4+
CONFIG=./deploy.conf
5+
LOG=/tmp/deploy.log
6+
TEST=1
7+
REF=
8+
ENV=
9+
10+
#
11+
# Output usage information.
12+
#
13+
14+
usage() {
15+
cat <<-EOF
16+
17+
Usage: deploy [options] <env> [command]
18+
19+
Options:
20+
21+
-C, --chdir <path> change the working directory to <path>
22+
-c, --config <path> set config path. defaults to ./deploy.conf
23+
-T, --no-tests ignore test hook
24+
-V, --version output program version
25+
-h, --help output help information
26+
27+
Commands:
28+
29+
setup run remote setup commands
30+
update update deploy to the latest release
31+
revert [n] revert to [n]th last deployment or 1
32+
config [key] output config file or [key]
33+
curr[ent] output current release commit
34+
prev[ious] output previous release commit
35+
exec|run <cmd> execute the given <cmd>
36+
console open an ssh session to the host
37+
list list previous deploy commits
38+
[ref] deploy to [ref], the 'ref' setting, or latest tag
39+
40+
EOF
41+
}
42+
43+
#
44+
# Abort with <msg>
45+
#
46+
47+
abort() {
48+
echo
49+
echo " $@" 1>&2
50+
echo
51+
exit 1
52+
}
53+
54+
#
55+
# Log <msg>.
56+
#
57+
58+
log() {
59+
echo "$@"
60+
}
61+
62+
#
63+
# Set configuration file <path>.
64+
#
65+
66+
set_config_path() {
67+
test -f $1 || abort invalid --config path
68+
CONFIG=$1
69+
}
70+
71+
#
72+
# Check if config <section> exists.
73+
#
74+
75+
config_section() {
76+
grep "^\[$1" $CONFIG &> /dev/null
77+
}
78+
79+
#
80+
# Get config value by <key>.
81+
#
82+
83+
config_get() {
84+
local key=$1
85+
test -n "$key" \
86+
&& grep "^\[$ENV" -A 20 $CONFIG \
87+
| grep "^$key" \
88+
| head -n 1 \
89+
| cut -d ' ' -f 2-999
90+
}
91+
92+
#
93+
# Output version.
94+
#
95+
96+
version() {
97+
echo $VERSION
98+
}
99+
100+
#
101+
# Run the given remote <cmd>.
102+
#
103+
104+
run() {
105+
local url="`config_get user`@`config_get host`"
106+
local key=`config_get key`
107+
if test -n "$key"; then
108+
local shell="ssh -A -i $key $url"
109+
else
110+
local shell="ssh -A $url"
111+
fi
112+
echo $shell "\"$@\"" >> $LOG
113+
$shell $@
114+
}
115+
116+
#
117+
# Launch an interactive ssh console session.
118+
#
119+
120+
console() {
121+
local url="`config_get user`@`config_get host`"
122+
local key=`config_get key`
123+
if test -n "$key"; then
124+
local shell="ssh -i $key $url"
125+
else
126+
local shell="ssh $url"
127+
fi
128+
echo $shell
129+
exec $shell
130+
}
131+
132+
#
133+
# Output config or [key].
134+
#
135+
136+
config() {
137+
if test $# -eq 0; then
138+
cat $CONFIG
139+
else
140+
config_get $1
141+
fi
142+
}
143+
144+
#
145+
# Execute hook <name> relative to the path configured.
146+
#
147+
148+
hook() {
149+
test -n "$1" || abort hook name required
150+
local hook=$1
151+
local path=`config_get path`
152+
local cmd=`config_get $hook`
153+
if test -n "$cmd"; then
154+
log "executing $hook \`$cmd\`"
155+
run "cd $path/current; \
156+
SHARED=\"$path/shared\" \
157+
$cmd 2>&1 | tee -a $LOG; \
158+
exit \${PIPESTATUS[0]}"
159+
test $? -eq 0
160+
else
161+
log hook $hook
162+
fi
163+
}
164+
165+
#
166+
# Run setup.
167+
#
168+
169+
setup() {
170+
local path=`config_get path`
171+
local repo=`config_get repo`
172+
run "mkdir -p $path/{shared/{logs,pids},source}"
173+
test $? -eq 0 || abort setup paths failed
174+
log running setup
175+
log cloning $repo
176+
run "git clone $repo $path/source"
177+
test $? -eq 0 || abort failed to clone
178+
log setup complete
179+
}
180+
181+
#
182+
# Deploy [ref].
183+
#
184+
185+
deploy() {
186+
local ref=$1
187+
local path=`config_get path`
188+
log deploying
189+
190+
hook pre-deploy || abort pre-deploy hook failed
191+
192+
# fetch source
193+
log fetching updates
194+
run "cd $path/source && git fetch --all"
195+
test $? -eq 0 || abort fetch failed
196+
197+
# latest tag
198+
if test -z "$ref"; then
199+
log fetching latest tag
200+
ref=`run "cd $path/source && git for-each-ref refs/tags \
201+
--sort=-authordate \
202+
--format='%(refname)' \
203+
--count=1 | cut -d '/' -f 3"`
204+
test $? -eq 0 || abort failed to determine latest tag
205+
fi
206+
207+
# reset HEAD
208+
log resetting HEAD to $ref
209+
run "cd $path/source && git reset --hard $ref"
210+
test $? -eq 0 || abort git reset failed
211+
212+
# link current
213+
run "ln -sfn $path/source $path/current"
214+
test $? -eq 0 || abort symlink failed
215+
216+
# deploy log
217+
run "cd $path/source && \
218+
echo \`git rev-parse --short HEAD\` \
219+
>> $path/.deploys"
220+
test $? -eq 0 || abort deploy log append failed
221+
222+
hook post-deploy || abort post-deploy hook failed
223+
224+
if test $TEST -eq 1; then
225+
hook test
226+
if test $? -ne 0; then
227+
log tests failed, reverting deploy
228+
quickly_revert_to 1 && log "revert complete" && exit
229+
fi
230+
else
231+
log ignoring tests
232+
fi
233+
234+
# done
235+
log successfully deployed $ref
236+
}
237+
238+
#
239+
# Get current commit.
240+
#
241+
242+
current_commit() {
243+
local path=`config_get path`
244+
run "cd $path/source && \
245+
git rev-parse --short HEAD"
246+
}
247+
248+
#
249+
# Get <n>th deploy commit.
250+
#
251+
252+
nth_deploy_commit() {
253+
local n=$1
254+
local path=`config_get path`
255+
run "cat $path/.deploys | tail -n $n | head -n 1 | cut -d ' ' -f 1"
256+
}
257+
258+
#
259+
# List deploys.
260+
#
261+
262+
list_deploys() {
263+
local path=`config_get path`
264+
run "cat $path/.deploys"
265+
}
266+
267+
#
268+
# Revert to the <n>th last deployment, ignoring tests.
269+
#
270+
271+
quickly_revert_to() {
272+
local n=$1
273+
log "quickly reverting $n deploy(s)"
274+
local commit=`nth_deploy_commit $((n + 1))`
275+
TEST=0 deploy "$commit"
276+
}
277+
278+
#
279+
# Revert to the <n>th last deployment.
280+
#
281+
282+
revert_to() {
283+
local n=$1
284+
log "reverting $n deploy(s)"
285+
local commit=`nth_deploy_commit $((n + 1))`
286+
deploy "$commit"
287+
}
288+
289+
#
290+
# Require environment arg.
291+
#
292+
293+
require_env() {
294+
config_section $ENV || abort "[$ENV] config section not defined"
295+
test -z "$ENV" && abort "<env> required"
296+
}
297+
298+
#
299+
# Update deploy.
300+
#
301+
302+
update() {
303+
log "updating deploy(1)"
304+
rm -fr /tmp/deploy
305+
git clone git://github.com/visionmedia/deploy.git \
306+
--depth 0 \
307+
/tmp/deploy \
308+
&> /tmp/deploy.log \
309+
&& cd /tmp/deploy \
310+
&& make install \
311+
&& log "updated $VERSION -> `./bin/deploy --version`"
312+
}
313+
314+
# parse argv
315+
316+
while test $# -ne 0; do
317+
arg=$1; shift
318+
case $arg in
319+
-h|--help) usage; exit ;;
320+
-V|--version) version; exit ;;
321+
-c|--config) set_config_path $1; shift ;;
322+
-C|--chdir) log cd $1; cd $1; shift ;;
323+
-T|--no-tests) TEST=0 ;;
324+
run|exec) require_env; run "cd `config_get path` && $@"; exit ;;
325+
console) require_env; console; exit ;;
326+
curr|current) require_env; current_commit; exit ;;
327+
prev|previous) require_env; nth_deploy_commit 2; exit ;;
328+
revert) require_env; revert_to ${1-1}; exit ;;
329+
setup) require_env; setup $@; exit ;;
330+
list) require_env; list_deploys; exit ;;
331+
update) update; exit ;;
332+
config) config $@; exit ;;
333+
*)
334+
if test -z "$ENV"; then
335+
ENV=$arg;
336+
else
337+
REF="$REF $arg";
338+
fi
339+
;;
340+
esac
341+
done
342+
343+
require_env
344+
345+
# deploy
346+
deploy "${REF:-`config_get ref`}"

deploy.conf

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[linode]
2+
user deploy
3+
host 178.79.150.42
4+
repo [email protected]:nko2/awegen.git
5+
ref origin/master
6+
path /home/deploy/app
7+
post-deploy npm install && [ -e ../shared/pids/node.pid ] && sudo restart node || sudo start node
8+
test sleep 1 && curl localhost >/dev/null

0 commit comments

Comments
 (0)