git-hacks

git-hacks Commit Details

Date:2012-10-28 19:59:06 (5 years 8 months ago)
Author:Nicola Fontana
Branch:master
Commit:383f6c5cb5010728ef66ef9eff2833dff6384b4b
Parents: deb05091eb243a5bda5bbc2e9425ce804c42a5eb
Message:web deployment: major reworking

The script now isolated the SilverStripe dependency in a single
function. The deployment has been improved by performing a
remote update from public before any git push.

Still lacking documentation and a way to force the synchronization of
remote from public without pushing.
Changes:
Dpost-receive.silverstripe (full)
Agitdeploy (full)

File differences

gitdeploy
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
# This script is expected to be sourced from git hooks.
#
# USAGE:
# source gitdeploy WEBDIR [FRONTEND]
#
# where WEBDIR is the (usually absolute) directory where the public
# website is contained. FRONTEND specifies the web framework to know
# how the data must be handled. If not specified, FRONTEND falls
# back to "dummy" (that is no-op).
#
# EXAMPLE:
# In the remote repository, create two hooks:
#
# #! /bin/sh
# # pre-receive hook
# source /path/to/gitdeploy /var/vhosts/mysite silverstripe
# public2remote
#
# #! /bin/sh
# # post-receive hook
# source /path/to/gitdeploy /var/vhosts/mysite silverstripe
# remote2public
error() {
echo "** $@" 1>&2;
}
[ -z "$1" ] && error 'gitdeploy requires a WEBDIR as first argument' && exit 1
webdir="$1"
frontend="$2"
[ -z "$frontend" ] && frontend=dummy
# Ovveride git to explicitely set its working directory to $webdir.
git() {
GIT_WORK_TREE="$webdir" command git "$@"
}
remote2public() {
echo "Syncing public with remote"
git checkout -qf
if [ ! -r "$webdir/bootstrap.cfg" ]; then return 0; fi
# Default bootstrap hook: $webdir/bootstrap can override it
bootstrap() {
}
source $webdir/bootstrap.cfg
if [ -n "${writables[*]}" ]; then
chmod 0777 ${writables[*]/#/$webdir/}
fi
bootstrap
}
# Get the value part of a key => value assignment from a PHP source.
# The approach using regex is quite flaky but way better than loading
# a whole PHP framework to get a freaking value.
lookup() {
sed -n "s/\s*['\"]$1['\"]\s*=>\s*['\"]\(.*\)['\"].*/\1/p" $2
}
refresh_dummy() {
return 0
}
refresh_silverstripe() {
local path="$1"
local cfg database server username password
for cfg in "$path"/*/_config.php; do
database="$(lookup database $cfg)"
[ -n "$database" ] && break
done
if [ -z "$database" ]; then return 1; fi
server=$(lookup server "$cfg")
[ -z "$server" ] && server=localhost
username=$(lookup username "$cfg")
password=$(lookup password "$cfg")
mysqldump -h"$server" -u"$username" -p"$password" \
--skip-lock-tables --skip-dump-date \
$database > $(dirname "$path")/"$database".sql
return 0
}
refresh_public() {
local dir subdomain
echo Refreshing MySQL dumps in public:
for dir in "$webdir"/*; do
if [ ! -d $dir ]; then continue; fi
subdomain="$(basename $dir)"
echo -ne "\t$subdomain... "
if refresh_$frontend "$dir" "$webdir/$subdomain.data"; then
echo done
else
echo not a subdomain
fi
done
}
public2remote() {
refresh_public
echo -n "Syncing remote with public... "
git add -A
if git diff --quiet --cached; then
echo not needed
return 0
else
git commit -qm 'Automatically updated by gitdeploy'
echo done
fi
}
[ -z "$1" ] && error No virtual host directory given
base=$1
export GIT_WORK_TREE="$base"
# Source the configuration file, if found in the virtual host
# directory. Define optional stuff, such as the "writables" array.
[ -r $base/post-receive.silverstripe.cfg ] && source $base/bootstrap.cfg
if [ -n "${writables[*]}" ]; then
echo Changing permissions of the writable directories
chmod 0777 ${writables[*]/#/$base/}
fi
echo Copying the current repository in the virtual host directory
git checkout -qf
echo Backing up MySQL data for every subdomain:
for dir in $base/*; do
if [ ! -d $dir ]; then
continue
fi
echo -ne "\t$(basename $dir)... "
database=
for file in $dir/*/_config.php; do
database=$(lookup database $file)
[ -n "$database" ] && break
done
if [ -z $database ]; then
echo not a subdomain
continue
fi
server=$(lookup server $file)
[ -z "$server" ] && server=localhost
username=$(lookup username $file)
password=$(lookup password $file)
mysqldump -h $server -u"$username" -p"$password" --skip-lock-tables --skip-dump-date $database > $dir.sql
echo $database
done
echo Committing changes on the remote side
git add $base/*.sql
git commit -qm 'Automatic backup'
remote2public
# Source the configuration file, if found in the virtual host
# directory. Define optional stuff, such as the "writables" array.
[ -r $base/post-receive.silverstripe.cfg ] && source $base/bootstrap.cfg
if [ -n "${writables[*]}" ]; then
echo Changing permissions of the writable directories
chmod 0777 ${writables[*]/#/$base/}
fi
post-receive.silverstripe
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
#! /bin/sh
#
# Standard code for performing bootstrap and backup
# operations on SilverStripe installations after a
# git push on the remote side. In other words, this
# is a way of deploying a SilverStripe based website
# using git.
#
# The only thing needed is the base directory of the
# virtual host, that is where the website will be
# published. This also means this script cannot be
# directly used as hook itself. You should wrap it
# with something such as:
#
# #!/bin/sh
# post-receive.silverstripe /var/www/website
#
# This script relies on some convention: by default,
# third level domains are expected to be direct
# descendants of the base path. In the example above,
# the main website is expected to be on
# /var/www/website/www.
#
# This script will:
#
# 1. checkout the HEAD of the bare repository into
# the base directory (deployment);
# 2. create a dump of the database (with mysqldump)
# for every valid SilverStripe site found in
# the first level subdirectories (backup);
# 3. autocommit the database dumps into the bare
# repository (commit).
#
# This means after a git push, a git pull will
# update the database dumps in the local repository.
#
# TODO: autocommitting of uploaded static files,
# such as video and images (usually found
# under assets/) is not yet implemented.
error() {
echo '**' $1
echo Usage: $0 VHOSTDIR
exit 1
}
lookup() {
sed -n "s/\s*['\"]$1['\"]\s*=>\s*['\"]\(.*\)['\"].*/\1/p" $2
}
[ -z "$1" ] && error No virtual host directory given
base=$1
export GIT_WORK_TREE="$base"
# Source the configuration file, if found in the virtual host
# directory. Define optional stuff, such as the "writables" array.
[ -r $base/post-receive.silverstripe.cfg ] && source $base/bootstrap.cfg
if [ -n "${writables[*]}" ]; then
echo Changing permissions of the writable directories
chmod 0777 ${writables[*]/#/$base/}
fi
echo Copying the current repository in the virtual host directory
git checkout -qf
echo Backing up MySQL data for every subdomain:
for dir in $base/*; do
if [ ! -d $dir ]; then
continue
fi
echo -ne "\t$(basename $dir)... "
database=
for file in $dir/*/_config.php; do
database=$(lookup database $file)
[ -n "$database" ] && break
done
if [ -z $database ]; then
echo not a subdomain
continue
fi
server=$(lookup server $file)
[ -z "$server" ] && server=localhost
username=$(lookup username $file)
password=$(lookup password $file)
mysqldump -h $server -u"$username" -p"$password" --skip-lock-tables --skip-dump-date $database > $dir.sql
echo $database
done
echo Committing changes on the remote side
git add $base/*.sql
git commit -qm 'Automatic backup'

Archive Download the corresponding diff file

Branches