Reputation: 1488
I would like to use git to deploy to a website to a testing server. My website is a wordpress theme built with gulp and the repository looks like
theme.git/
-- gulpfile.js
-- src/
-- build/
I've followed the steps explained here and here which are- set up a bare repository on the server, configure the location of git work tree and write a post-receive hook to checkout the repo to that location.
The problem is I'm only looking to move or copy the build/
folder to it's location on the server. My only thought was to write a post-receive hook to that pulls the repo to one work tree location (because I think I read that bare repos don't typically have a work tree at all), and then cp
's the build folder into wp-content/themes/
It seems unnecessarily complicated so I'm wondering if there's a more efficient / more common way to go about it. Thanks!
Upvotes: 18
Views: 1129
Reputation: 6857
I use git for deployment all the time. There's nothing weird about it at all, and I don't know what @cido has against it. There's a great deal of value in being able to go back in time to any point on your 'deploy' branch and being able to see precisely what was live on your server at that time.
Don't confuse the git repo that you're using for storage vs the one that you're using for deployment. You should have a completely clean git tree checked out into your production area (whatever that is) and as I suggested you may want to have a separate branch called 'deploy' or 'production' or 'staging' or whatever.
Your post-receive hook then just needs to run a script that goes into your production area, and pulls your deploy branch to update.
If you need this to be robust against files being placed there outside of what git will do (e.g. temp files generated at runtime) then you may want to call git clean -dfx
before pulling. And there are other things that you might want to do if you're expecting this server to be rebuilt from scratch on a regular basis (e.g. in a cloud deployment) but it sounds like doing the initial setup manually should be OK for your use case.
cp
ing the build directory into place sounds fine, only I'd use rsync because it'll generally be faster if the changes are only incremental.
Upvotes: 1
Reputation: 15139
I would divide your project into two repos.
Source. Includes source and whatever. Excludes the /build/ directory. Use this only for source control. This never goes to the website (it may be unsafe to store your code on the website, even in the form of a git repo).
Deployment. Only /build/ directory. You can initiate a new git repo inside the directory. This has a remote repo on the server; you can use the post-receive hook to deploy, as before.
Upvotes: 0
Reputation: 60635
This is straightforward git read-tree
work. Keep a manifest aka index for what's in your deployment directory and handle your updates with a pre-receive like so:
#!/bin/sh
while read old new ref; do [[ $ref = refs/heads/master ]] && {
export GIT_INDEX_FILE=deployment-manifest
export GIT_WORK_TREE=/path/to/deployment
git read-tree -um `git write-tree` $new:build || exit 1
}; done
Note that if some file being deployed this way has been changed in the deployment tree, the git read-tree
here and the push will fail because git won't overwrite content you haven't told it about.
Upvotes: 3
Reputation: 454
Your approch for using git
so extensively for the deployment seems a bit weird, mainly because git is primary a source code management system, not a deployment tool. It is true that you can do many kind of weird stuff with git hooks, but for some reason or another I feel those a tendency to return to haunt you.
Normally I would recommend you to use somekind of continuous integration tool for the job. One possible workflow, which I could use myself, would be
gulp build
(or whatever your task name is) there, so you wouldn't have to store the build
directory in the git repo at all.after_success
hook you could then copy the build directory to the target server for example by using scp
. Here is an example of doing the very same thing with FTP. Travis supports encryption of sensitive data, so you don't have to worry (at least so much) about storing username and password in the git repo.That flow is useful when you want to deploy the build everytime you commit something to the git repo. BTW, when you use it for the first time it really feels like magic: "I just made this git push
, and now the change is already live on my server."
However you mentioned that you want to deploy the code to a testing server. It is true that CI tools (such as Travis) can be used to maintain a flow between different deployment steps, out of which many are testing servers. One example flow for large projects could be
development -> tests passing? -> release -> tests passing? -> integration -> tests passing? -> staging -> tests passing? -> production
...where the flow could be either partly or fully automated with a CI tool.
However you made it sound like that in your case deploying of build is kind of a one-time thing, which you sometimes just want to do manually. (I apologize if I misinterpreted you.) For these kind of one-time tasks the use of shell scripts or task management tools is more fitting.
You mentioned that you're already using gulp
. That's a very handy tool for the job, especially because you can easily combine different "streams of tasks". You could have one task for building the theme (gulp build
) and another for test server deployment (gulp deploy-test
), which just extends the build
task with an additional step for copying of files to the test server. gulp-scp looks like a fine plugin for the task (I haven't used it myself though, it was just the first search result from google). If that does not work out, you can always call scp
manually with gulp-shell or similar.
You could even parametrize the deployment tasks so you could do something like:
gulp deploy --test
and
gulp deploy --production
There you go, this was your first lesson in devops. There's a whole world of things to learn if this kind of task automation in software projects sounds interesting to you.
Upvotes: 5