My Dev Setup, part 4: Version Control and Deployments with WordPress
In an earlier post, I promised to shed some light on our git workflow for WordPress projects. The above image sums it up pretty nicely, but read on for the details.
Most of the development we do happens in a local Apache + PHP + MySQL environment, using MAMP Pro. That means I have a local copy of each site I’m developing, which creates some overhead compared to everyone just working on a central dev server. It’s worth it though because it makes working on different features and code branches easy.
Every project has its own git repository, which we set to the WordPress root directory. This is because most of our projects involve a combination of custom themes and plugins, and it makes sense to group them in a single repository. We still don’t want any of the core WordPress code in git, so we use a .gitignore file based on this excellent template by Joe Bartlett:
The above means that in practice the contents of a typical project repository structure looks somewhat like this:
/ +-- wp-content/ |-- plugins/ | +-- custom-plugin/ | +-- theme/ +-- custom-theme/
Sharing code and automated staging with Beanstalk
When I want to share code with my colleagues or am ready to something to a client, I do a git push to a central repository hosted on Beanstalk. Beanstalk has loads of useful features, but the best thing about it has to be the simple deployments it offers. For all projects, we set up automated deployments to a staging server, where we have copies of each site. Deployments to production are also set up in Beanstalk, but (intentionally) require a manual click in the web app.
Going to production
Finally, moving from staging to production can require some tricky search-and-replacing domains and absolute paths in the database. WordPress in Network mode tends to be particularly keen on saving the site URL in way too many places. One way to do this is to perform a search and replace on a SQL dump, but we use this nifty tool by Interconnect/IT, because it correctly handles serialised strings, which are often used in WordPress for things like widget options etc. The same tool is useful when doing the reverse, ie. creating a local copy of an existing site.