Skip to content

Commit ffa2829

Browse files
committed
Add deploy script
1 parent b5c6495 commit ffa2829

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed

deploy.sh

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
#!/usr/bin/env bash
2+
set -o errexit #abort if any command fails
3+
me=$(basename "$0")
4+
5+
help_message="\
6+
Usage: $me [-c FILE] [<options>]
7+
Deploy generated files to a git branch.
8+
9+
Options:
10+
11+
-h, --help Show this help information.
12+
-v, --verbose Increase verbosity. Useful for debugging.
13+
-e, --allow-empty Allow deployment of an empty directory.
14+
-m, --message MESSAGE Specify the message used when committing on the
15+
deploy branch.
16+
-n, --no-hash Don't append the source commit's hash to the deploy
17+
commit's message.
18+
-c, --config-file PATH Override default & environment variables' values
19+
with those in set in the file at 'PATH'. Must be the
20+
first option specified.
21+
22+
Variables:
23+
24+
GIT_DEPLOY_DIR Folder path containing the files to deploy.
25+
GIT_DEPLOY_BRANCH Commit deployable files to this branch.
26+
GIT_DEPLOY_REPO Push the deploy branch to this repository.
27+
28+
These variables have default values defined in the script. The defaults can be
29+
overridden by environment variables. Any environment variables are overridden
30+
by values set in a '.env' file (if it exists), and in turn by those set in a
31+
file specified by the '--config-file' option."
32+
33+
bundle exec middleman build --clean
34+
35+
parse_args() {
36+
# Set args from a local environment file.
37+
if [ -e ".env" ]; then
38+
source .env
39+
fi
40+
41+
# Set args from file specified on the command-line.
42+
if [[ $1 = "-c" || $1 = "--config-file" ]]; then
43+
source "$2"
44+
shift 2
45+
fi
46+
47+
# Parse arg flags
48+
# If something is exposed as an environment variable, set/overwrite it
49+
# here. Otherwise, set/overwrite the internal variable instead.
50+
while : ; do
51+
if [[ $1 = "-h" || $1 = "--help" ]]; then
52+
echo "$help_message"
53+
return 0
54+
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
55+
verbose=true
56+
shift
57+
elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
58+
allow_empty=true
59+
shift
60+
elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
61+
commit_message=$2
62+
shift 2
63+
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
64+
GIT_DEPLOY_APPEND_HASH=false
65+
shift
66+
else
67+
break
68+
fi
69+
done
70+
71+
# Set internal option vars from the environment and arg flags. All internal
72+
# vars should be declared here, with sane defaults if applicable.
73+
74+
# Source directory & target branch.
75+
deploy_directory=build
76+
deploy_branch=gh-pages
77+
78+
#if no user identity is already set in the current git environment, use this:
79+
default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
80+
default_email=${GIT_DEPLOY_EMAIL:-}
81+
82+
#repository to deploy to. must be readable and writable.
83+
repo=origin
84+
85+
#append commit hash to the end of message by default
86+
append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
87+
}
88+
89+
main() {
90+
parse_args "$@"
91+
92+
enable_expanded_output
93+
94+
if ! git diff --exit-code --quiet --cached; then
95+
echo Aborting due to uncommitted changes in the index >&2
96+
return 1
97+
fi
98+
99+
commit_title=`git log -n 1 --format="%s" HEAD`
100+
commit_hash=` git log -n 1 --format="%H" HEAD`
101+
102+
#default commit message uses last title if a custom one is not supplied
103+
if [[ -z $commit_message ]]; then
104+
commit_message="publish: $commit_title"
105+
fi
106+
107+
#append hash to commit message unless no hash flag was found
108+
if [ $append_hash = true ]; then
109+
commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
110+
fi
111+
112+
previous_branch=`git rev-parse --abbrev-ref HEAD`
113+
114+
if [ ! -d "$deploy_directory" ]; then
115+
echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
116+
return 1
117+
fi
118+
119+
# must use short form of flag in ls for compatibility with OS X and BSD
120+
if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
121+
echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
122+
return 1
123+
fi
124+
125+
if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
126+
# deploy_branch exists in $repo; make sure we have the latest version
127+
128+
disable_expanded_output
129+
git fetch --force $repo $deploy_branch:$deploy_branch
130+
enable_expanded_output
131+
fi
132+
133+
# check if deploy_branch exists locally
134+
if git show-ref --verify --quiet "refs/heads/$deploy_branch"
135+
then incremental_deploy
136+
else initial_deploy
137+
fi
138+
139+
restore_head
140+
}
141+
142+
initial_deploy() {
143+
git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
144+
git --work-tree "$deploy_directory" add --all
145+
commit+push
146+
}
147+
148+
incremental_deploy() {
149+
#make deploy_branch the current branch
150+
git symbolic-ref HEAD refs/heads/$deploy_branch
151+
#put the previously committed contents of deploy_branch into the index
152+
git --work-tree "$deploy_directory" reset --mixed --quiet
153+
git --work-tree "$deploy_directory" add --all
154+
155+
set +o errexit
156+
diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
157+
set -o errexit
158+
case $diff in
159+
0) echo No changes to files in $deploy_directory. Skipping commit.;;
160+
1) commit+push;;
161+
*)
162+
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2
163+
return $diff
164+
;;
165+
esac
166+
}
167+
168+
commit+push() {
169+
set_user_id
170+
git --work-tree "$deploy_directory" commit -m "$commit_message"
171+
172+
disable_expanded_output
173+
#--quiet is important here to avoid outputting the repo URL, which may contain a secret token
174+
git push --quiet $repo $deploy_branch
175+
enable_expanded_output
176+
}
177+
178+
#echo expanded commands as they are executed (for debugging)
179+
enable_expanded_output() {
180+
if [ $verbose ]; then
181+
set -o xtrace
182+
set +o verbose
183+
fi
184+
}
185+
186+
#this is used to avoid outputting the repo URL, which may contain a secret token
187+
disable_expanded_output() {
188+
if [ $verbose ]; then
189+
set +o xtrace
190+
set -o verbose
191+
fi
192+
}
193+
194+
set_user_id() {
195+
if [[ -z `git config user.name` ]]; then
196+
git config user.name "$default_username"
197+
fi
198+
if [[ -z `git config user.email` ]]; then
199+
git config user.email "$default_email"
200+
fi
201+
}
202+
203+
restore_head() {
204+
if [[ $previous_branch = "HEAD" ]]; then
205+
#we weren't on any branch before, so just set HEAD back to the commit it was on
206+
git update-ref --no-deref HEAD $commit_hash $deploy_branch
207+
else
208+
git symbolic-ref HEAD refs/heads/$previous_branch
209+
fi
210+
211+
git reset --mixed
212+
}
213+
214+
filter() {
215+
sed -e "s|$repo|\$repo|g"
216+
}
217+
218+
sanitize() {
219+
"$@" 2> >(filter 1>&2) | filter
220+
}
221+
222+
[[ $1 = --source-only ]] || main "$@"

0 commit comments

Comments
 (0)