As I have grown as a developer, the single greatest change I made was switching to using version control. My weapon of choice – as with most developers – is git. The idea of editing a site over FTP now makes me cringe.
Once I got familiar with git, it became apparent that I wasn’t using it particularly well or efficiently. With a bit of research, experience and many issues, I’ve settled on a development workflow which works nicely for me.
The root of it all is branches (pun wholly intended; you’re welcome).
My particular workflow is built around my typical project setup, but it will broadly apply to most people with some additions, omissions and tweaks. I’m a huge fan of WP Engine, not least because it gives you git access as well as a staging site to work with. As such, every project I run on WP Engine has two remotes on the hosting side: production and staging.
Furthermore, because I collaborate with other developers on my projects, I use GitHub (with private repositories) as our central codebase and project management tool. This is then a third remote for my project (I call my GitHub remote “origin”).
With GitHub as our main codebase library, a staging site for client review and a production site in addition to my local development environment using Varying Vagrant Vagrants, I have everything I need to manage a project.
Branch all the things
Branching is an incredibly powerful tool. It allows you to take the current state of your codebase, copy it and make changes to it without affecting the original codebase, meaning that you can develop something while the live codebase for your site remains intact. This way, you can build, test, review, delay, trash and procrastinate without breaking your site. Once everything is built the way you want, you simply “merge” your development branch into your master branch and push it live. Seamless, smooth and robust.
If you’re not yet familiar with branches, trust me that they’re a godsend and you’ll want to use them, so get into the habit of branching as soon as possible. The sooner you can get into a good habit, the easier the transition will be and the more prepared you’ll be for when your projects expand and get more complicated with other developers assisting.
Here’s my workflow. Any time anything needs to be worked on on the site, a new branch is created. This is almost without exception (I’ll make exceptions for fixing typos, adding single CSS rules etc.). Branches are classified into two groups: features and issues. When something breaks, it’s an issue; when something new is wanted, it’s a feature.
Branches are named descriptively for easy reference and are nested into these two groups, so if a client wanted a new home page layout, I’d create a branch called feature/new-home-page:
or if the client came to me and said that his shortcode which displays his age is not working, I’d create a branch called issue/age-shortcode:
GitHub (or whatever git server you choose to use) is where you push these branches if you want to store them or collaborate with other developers on them.
Once you and your colleagues have finished working on the new feature, or fixing the issue, you’re ready to show it to the client for his review. The feature and issue branches that I’ve spoken about so far are development branches, for organising code and collaborating. Now a new type of branch comes in to play: environment branches.
Your local development environment notwithstanding, you’ll have a certain number of other environments for your code. As I mentioned, my typical setup includes a staging site and a production site, each of which is its own environment. These environments should have their own branch which precisely mimics what’s on that site, so in my case, I have a branch called staging and a branch called production.
When you’re ready to add your feature or bug fix to a site, either for your client to review (more likely with features) or to go live (more likely with issues), you need to merge that development branch into the environment branch and then push that environment branch to the remote.
This means that there’s only ever one branch on your staging/production remotes. The reasons for doing this are many, but the main one for me is that you want to be able to push several features or bug fixes to an environment at the same time without waiting for one to be resolved before working on the next one.
Let me show you an example. Let’s say a client wants me to build a new layout for the home page. I create the new home page layout and want him to take a look at it. Meanwhile, he’s asked me to also add Doubleclick for Publishers ad zones to his theme. I build that and want him to take a look at it as well before going live.
If I did all of this on the master branch, it would look something like this:
That works OK, but the issue comes when the client is happy with the DFP integration and wants to go live with it but still needs you to tweak the home page layout. You can’t push master to production because then the new home page layout will be there also and you can’t (easily) push just the DFP changes to production either.
The better way to do it is more like this:
Because each development activity and each hosting environment has its own branch, it’s easy to separate things out and get exactly what you want where you need it. Hopefully this example shows how just two simultaneous development tasks necessitates a robust branching strategy like this.
Using GitHub issues
GitHub is so handy and easy for managing projects. Its issues feature allows you to easily track and collaborate on development tasks with great ease. I open an issue for each task that needs done and use labels to organise them. With GitHub’s ability to close issues from commit messages, it becomes an incredibly powerful tool for managing an entire project.
This workflow has come about as a result of my own experiences and research but I by no means consider myself an expert on git or development, so I’m very much open to hearing how you develop and what strategies you like you to use to manage your projects. Please contribute your thoughts in the comments below.