Deploying a WordPress Theme with Git

By @zachfeldman
Written on Sep 24, 2014

You probably think I’m crazy just after reading that title. “Zach,”, you say, the words escaping your lips with a growing sense of urgency, panic, and fear, “isn’t it a HUGE AMOUNT OF OVERKILL to deploy changes to a WordPress theme using git?”

I’m here to tell you that no, my dear reader, it’s not. I’m here to tell you that it’s raised developer productivity, made us deploy more often, and increased revenues by 3,000%. Only one of those statements is not true.

The git-based deploy process is usually reserved for “Apps of the New Age”. We’re talking Sinatra, Rails, Node, Meteor, and all of these newfangled app creation platforms. Seemingly everyone has git based deployment.

You’re a forward-thinking developer that has to make changes often to a WordPress-based website that involve the actual templates that power it, whether that includes changing your office address, modifying the way classes are displayed, or deploying a brand new landing page (our biggest use case). Taking 20-30 minutes to set this up might be a wise move that makes deployment consistent across your stack.

The Meat and Potatoes

Great, I’ve convinced you. Welcome to the important part of the article, where you can copy and paste all of the answers to your most vexing questions.

If you’re like me, you’re constantly looking for ways to optimize how your website runs. I put together all of these ways into a toolkit I like to call “wordpress-haml-sass”. It allows me to use my favorite templating language, HAML and my favorite CSS precompiler, SASS. It also closure-compiles all of the JavaScript down into one tiny file. This way we have less requests overall for all of those pesky disparate and unminified JS files.

You can check out wordpress-haml-sass here.

The point being that the repository for my WordPress projects isn’t just a theme directory with PHP files. It’s a bunch of HAML, SASS, and JavaScript files that get bundled into a theme by a makefile. So when I push up the NYCDA website theme to production I only want to copy over this “theme” directory to the wp-content/themes folder. I don’t want to copy the rest of the miscellaneous project files in my GitHub repository, a common problem when doing WordPress theme dev. This is where the post-receive script comes in, which I’ll go into later on in this article.

The Real Meat and Potatoes

Ok, so maybe that wasn’t the real meat and potatoes, but here we go, for realsies this time! The step by step you’ve all been waiting for.

Get SSH Access to your Server

1
ssh myusername@myserver.com

Make sure that that gets you “in” as they say in all of those hacker movies.

Setup Authenticated SSH Access to your Server

This whole thing will be a lot easier and more possible if the remote server that you’re looking to access has your SSH key, so you can access it without having to enter a password every time.

On the machine in the cloud where your site is hosted:

1) Create a .ssh directory in your users folder if it doesn’t exist

1
mkdir ~/.ssh

On your local machine:

1) Make sure you have an SSH key generated. If you don’t, follow these instructions.

2) Ensure your SSH key and directory have the right permissions:

1
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*

3) Send your SSH key to the remote server (assuming it goes by the default name, id_rsa.pub):

1
cat ~/.ssh/id_rsa.pub | ssh root@yourdomain.com 'cat - >> ~/.ssh/authorized_keys'

Finally, on the remote server, ensure the permissions are correct for this newly added key:

1
chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh/

You should now be able to SSH onto your remote server without being prompted for a password!

Create a Bare Version of your Repository

1) Clone a “bare” version of your repo:

1
git clone --bare git@github.com:yourusername/yourrepo.git

2) Get this version of your repo up on your server. I like to use scp (Secure Copy) on the command line but heck, you could even use FTP if you want to be old fashioned about getting this going. We put this bare repo in the same folder that the html/ folder lives in, so one level up from the web root. There’s also a “deploy” folder in there used to temporarily hold the theme, but more on that later.

1
scp -r yourrepo.git jeff@lebowski.org:~/domains/yoururl.com

3) Configure your post-receive script. This is, as they say, “where the magic happens”. Your post-receive script is a Ruby script (in our case, notice the shebang) that lets you do stuff after a push has been made to your version of the repository on the server. Ours looks like it was copied from a blog post because, well, it was! You can see this script inside of your bare repository (cd bare-repo.git) inside of the “hooks” directory. If you don’t have one, just create a file with the name post-receive in that hooks directory. Also make sure that it has the right permissions to run (chmod +x post-receive).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env ruby # post-receive # 1. Read STDIN (Format: "from_commit to_commit branch_name") from, to, branch = ARGF.read.split " " # 2. Only deploy if master branch was pushed if (branch =~ /master$/) == nil puts "Received branch #{branch}, not deploying." exit end # 3. Copy files to deploy directory deploy_to_dir = File.expand_path('../deploy') `GIT_WORK_TREE="#{deploy_to_dir}" git checkout -f master` `cp -r ../deploy/theme ../html/wp-content/themes/theme` `rm -rf ../html/wp-content/themes/nycda-2014` `mv ../html/wp-content/themes/theme ../html/wp-content/themes/nycda-2014` puts "DEPLOY: Master copied to theme directory."

So the script is pretty darn simple. We checkout master and put it in a temporary directory called “deploy”. Then, we copy the theme into the wp-content/themes folder with the name “theme”. We delete the old version of the theme and then immediately rename the new theme folder to the old version of the theme’s name. Then we output a logging message saying this has all been done.

Add A “Prod” Remote to your Theme’s Git Repo

The final step is adding this brand new remote to push to to your theme’s Git repository. Before this is done, double check that everything worked out by just pushing to the remote:

1
git push ssh://yourusername@yoursite.com/domains/yoursite.com/yourrepo.git master

If this works out, then add a shortcut:

1
git remote add production ssh://yourusername@yoursite.com/domains/yoursite.com/yourrepo.git

and then you can just push to that:

1
git push production master

Pretty awesome, right? Well, I’m glad that I think so.

One final caveat: if you’re using a plugin like WP Super Cache for caching of your pages, you’ll have to bust the cache as well. I wrote a simple script to do it that I have to login to prod to run, but I have a ton of aliases locally and on prod so it take about 3 seconds to do.

Hopefully, deploying your WordPress theme with Git will lead to lots of fun and profit for you, the enterprising web developer! Good luck out there.

Sources: Kris Jordan + The MediaTemple Knowledge Base.

X-posted from the New York Code + Design Academy blog.





Sign up for our e-mail list to hear about new posts.