Since the time I discovered the full potential and benefits of using version control systems like SVN or Git, my inclination towards using them has transformed into a full-blown addiction. I use it for everything — projects, websites, documents or any other crap. Even for binaries — till I realized one day I was out of disk space.
I can’t imagine how software engineers and developers who don’t use subversion (or any version control system for that matter) live with themselves. But then again there are people who like Ricky Martin (no offense).
I was about to import FuzedBulb — which is now based on WordPress — into my SVN repository when I realized that I have atleast five other projects running on WordPress and a few more are lined up (including my dad’s website — which, guess who is going to work on?). To be honest, it is a pain to upgrade them individually once a new version of WordPress or a plugin is out. Though I must admit that it is much better nowadays since the introduction of one-click update feature. However, even with that it is cumbersome and also I would rather prefer to manage everything in subversion than modifying live copies (see my addiction kicking in). Besides, if I recall correctly I don’t think I have FTP daemon anymore on my VPS which is what the WordPress auto update feature utilizes.
If you recall your software engineering 101 — repetition tends to make things a bit unmanageable at times. This calls for some SVN refactoring.
So what do I want?
Ideally, I want the core wordpress installation to be shared among the projects along with some common plugins like SEO, Google Analytics, WP Super Cache and Google Sitemap etc. This way all I have to do is update the one-and-only copy to the latest version and it should just propagate through to all projects using it.
I thought of organizing it as:
REPOSITORY: wp-core # WordPress core installation wp-plugins # Common plugins wp-themes # Common themes / framework (e.g. thematic) FuzedBulb.com # Project specific plugins & themes
Now some of the itchy requirements are :
- A project can have its own theme (duh!)
- A project can have its own set of additional plugins
- A project can have modified versions of common plugins (e.g. wp-super-cache path can be different for each project)
I think if I am able to meet these requirements, I will have enough flexibility to override plugins and themes and still be able to have maximum share-ability. TeaBreak uses a bunch of custom and modified plugins so these requirements / situations are not improbable.
I have found svn:externals property to be quite useful at times. You can set this property to pull in files from an external repository into a specified folder. This works very well for WordPress, especially for plugins – here’s a good article on how to pull in latest releases from SVN directly using externals.
So for FuzedBulb project all I have to do is:
$ cd FuzedBulb.com $ svn propedit svn:externals . core svn://repository/wordpress-core/ core/wp-content/plugins/ svn://repository/wordpress-plugins/ core/wp-content/themes/ svn://repository/wordpress-themes/ core/wp-content/themes/ svn://repository/FuzedBulb.com/
But hold on — you see the last line, that is not going to work because you can not pull in multiple external projects into the same directory (it screws up the .svn metadata folder which stores information like svn repository location etc. and in this case there’s a conflict as to what the repository location should be).
core svn://repository/wordpress-core/ core/wp-content/plugins/ svn://repository/wordpress-plugins/
Additionally, there’s a bigger problem — core is itself an externally pulled directory and so therefore can not have an additional externally pulled source into itself (i.e. core/wp-content/plugins/).
So, what do I do? I could move wp-content outside of the core — but then that doesn’t really fulfill my requirements because I still want to be able to pull in from multiple external sources which I can’t do with svn:externals (see requirement # 3). As much as I want to, I can’t use svn:externals for this purpose unfortunately. What I am actually looking for is composition or a compilation support.
First of all, I will stop you if you’re trying to google “depro”. You won’t find it. Its a collection of really trivial perl scripts (code-named: depro) that I wrote back in 2008/09. I will dedicate a separate post explaining what it does, but for now I will keep it very simple. What depro does is:
- checks out from multiple SVN sources
- copies / overwrites everything verbatim (in order) to a destination folder
- copies appropriate config files based on “hostname”
- e.g. in our case a different wp-config.php will be copied when running depro on live host compared to my dev env
Just to be clear, it’s not exactly as simple as it looks like; but really, you get the point, at the end of the day I just need a bunch of svn co and cp magic to meet all the requirements.
Life is looking good…
So what I have done is that I have created the repository structure as I have described above. I am using this for FuzedBulb but the plan is to refactor other wordpress projects to follow suit. Once done, WordPress will suddenly become amazingly easier to maintain, quicker to update and manageable for multiple projects. Problem solved.
Additionally, I have also configured FuzedBulb into depro’s auto-deployment cron job which runs every mid-night. I use this for auto-deploying most of the projects that I maintain including TeaBreak.
It’s all fitting well. Now, all I have to do now is check broken stuff in to my SVN repository and forget about it. It should be live by the time I wake up the next morning.
By the way, to get an alternate perspective, I am really interested in hearing your thoughts and comments on this issue. How do you manage your WordPress installations and subsequent core/plugin updates (especially in the given setting when you’ve multiple projects and you use version control)?