Reputation: 313
I run following bash script in cronjob to update my web site
#!/bin/bash
cd /home/username/public_html
git pull origin master
This cronjob is run every 5 minutes, so if i commit changed to git repo, it get pulled to live web site.
What i want to do is, each time this script run, check if a particular file is changed, run a curl/wget command if the file is changed.
The file i need to track for changes are style.css and script.js
What i am doing is, if these file is changed, update revision number of the script in my web site template, so cache is cleared and latest changed css and js file is loaded.
<link href="/css/style.css?REVISION_NUMBER_HERE" rel="stylesheet" type="text/css">
I can increase JS/CSS revision number easily with a curl request as it is stored in mysql DB.
Here is a sample git pull result, so we can grep for that style.css/script.js in the result
* branch master -> FETCH_HEAD
Updating cbd0d46..36aeed6
Fast-forward
admin/cf.php | 16 ++++++++++++++++
css/style.css | 47 +++++++++++++++++++++++++++--------------------
include/common.php | 1 +
templates/header.tpl | 4 ++--
templates/index.tpl | 13 ++++++-------
5 files changed, 52 insertions(+), 29 deletions(-)
EDIT
Thanks @torek for the reply.
I need some more help with BASH scripting, now here is my test git command.
[root@server70 public_html]# git diff --name-only 8613bd3ed718b27ca680bdf33e0a4b32b0f58b8c HEAD | egrep '.css|.js|.tpl'
css/style.css
templates/header.tpl
templates/index.tpl
templates/user/delete.tpl
[root@server70 public_html]#
I put hard coded git rev number for testing. My bash script
[root@server70 public_html]# sh 1.sh
File changed css/style.css
File changed templates/header.tpl
File changed templates/index.tpl
File changed templates/user/delete.tpl
[root@server70 public_html]# cat 1.sh
#!/bin/bash
CSS_JS_CHANGED=0
git diff --name-only 8613bd3ed718b27ca680bdf33e0a4b32b0f58b8c HEAD | egrep '.css|.js|.tpl' |
while read name; do
CSS_JS_CHANGED=1
echo "File changed $name"
done
if [ "$CSS_JS_CHANGED" = "1" ]; then
echo expression evaluated as true
fi
[root@server70 public_html]#
If i run my script inside while, it get executed multiple times if multiple files changed. I only need to run my script once per change.
So i Need to set a variable CSS_JS_CHANGED, set its value to 0. Then if a file change is detected, set its value to 1. Then run my script if value of CSS_JS_CHANGED is 1.
But for some reason, i can't set value of CSS_JS_CHANGED to 1 inside the while loop. Anything to do with variable scope ?
** EDIT 2 **
I find why i can't set variable from inside while loop here
Being a bash noob, can someone get my script working please :)
EDIT 3
Got it working with out CSS_JS_CHANGED variable.
[root@server70 public_html]# cat update
#!/bin/bash
# */5 * * * * /home/USERNAME/public_html/update >/dev/null 2>&1
cd /home/USERNAME/public_html
OLD_HEAD=$(git rev-parse HEAD)
git pull origin master
NEW_HEAD=$(git rev-parse HEAD)
[ $OLD_HEAD = $NEW_HEAD ] && exit 0
git diff --name-only $OLD_HEAD $NEW_HEAD | egrep '.css|.js' |
while read name; do
touch /tmp/css_js_update
done
if [ -f "/tmp/css_js_update" ]
then
/usr/bin/curl 'http://mywebsite.com/admin/cf.php?js_version_update=mywebsite'
rm -f /tmp/css_js_update
fi
[root@server70 public_html]#
Now waiting for a .css/.js file commit :)
Thanks again @torek
Upvotes: 5
Views: 4658
Reputation: 488193
Any time you do this sort of thing you should ask: "changed with respect to what?"
If you're deploying stuff to a web server, presumably you mean "changed from the version the server read". In which case, start by saving something about the version the server read, such as "the contents", or—in the case of git, where this is easy—a unique-identifier for the version the server read.
It seems like you're doing a git pull
directly on the server (which has some drawbacks but let's just run with that). Rather than attempting to interpret git merge
output, it would seem to be simpler to capture some SHA-1 values. For instance, you could grab those for the two file blobs you're interested in:
OLD_STYLE_ID=$(git rev-parse HEAD:css/style.css)
OLD_SCRIPT_ID=$(git rev-parse HEAD:script.js) # fix path here if/as needed
After that you can do the fetch-and-merge / pull operation, then get the new SHA-1s:
git pull origin master
NEW_STYLE_ID=$(git rev-parse HEAD:css/style.css)
NEW_SCRIPT_ID=$(git rev-parse HEAD:script.js) # again, fix path if needed
Now if the new IDs match the old IDs, those files are unchanged; any IDs that do not match represent a change in those files.
Alternatively, save the IDs for the old and new HEAD
values, and if those change, do something with the interesting path(s), e.g.:
OLD_HEAD=$(git rev-parse HEAD)
git pull origin master
NEW_HEAD=$(git rev-parse HEAD)
[ $OLD_HEAD = $NEW_HEAD ] && exit 0 # no change to repo = no change to any files
At this point there are many options, such as:
git diff --name-only ${OLD_HEAD} ${NEW_HEAD} -- css/style.css script.js |
while read name; do
...
done
or simply check whether git diff --name-only
, restricted to those paths (as above), prints anything at all.
Upvotes: 7