Automatic deployment from BitBucket

I’ve just stumbled upon this BitBucket sync script which works great! It can download the (master) branch as a ZIP archive and unzip it to deployment folder. But aside from that, combined with a BitBucket’s POST hook, it can pick-up latest commits and update file-by-file directly from repository, so you can keep your live website up-to-date automatically!

Using POST hook BitBucket will notify the script about any commits pushed to the repo, and script can process each of them and update modified (or added/removed) files one-by-one easily.

Since this is a ready-to-use script which doesn’t suit my needs perfectly, I have just forked it as a private repository (and will most likely make it public later, as I progress) in an attempt to rewrite it as a PHP class (or set of classes) to be used in other applications.

build.bat to the rescue

For almost three years now I’ve been manually building Real Estate Script (and Instant Update while it was closed-source) for release, which means for each version I had to do this:

  • 1. put old version in one folder
  • 2. compare old with development version and extract only modified files
  • 3. merge the two versions into a new version, in separate folder
  • 4. encode new version with ionCube into separate folder
  • 5. copy certain encoded files over new version
  • 6. pack the new version files into a ZIP archive for distribution

 

…and I’ve been doing that for each license type, every time we were publishing a new version of the script, so I had to repeat last two steps five times for branded (white label) version, regular version, free-trial version, branded (white label) upgrade and regular version upgrade, to get five different ZIP files for distribution. Free trials do not have upgrade package as they work only 30 days.

And this was not a problem. After couple of versions I got into the routine so I could do all of this for about three hours (for all five versions), while step #2 was taking most of the time (about 30-45) minutes. But the real problems appeared when after building all ZIPs I realized we had a bug in the code, so I had to update all five ZIPs manually. There were misplaced files everywhere, updating 3 or 4 out of 5 archives, then forgetting to update source folders (from which I initially created ZIP files), and so on…

It all got worse after PHP 5.3 (and 5.4) was getting installed on more and more servers, because strangely, ionCube uses different encoding algorithm and thus requires different (encoded) files for PHP versions up to 5.3 and for versions 5.3 and above. So, over night, number of ZIP files to manage jumped from five to ten!

Today I spent about three hours writing a batch command script named simply build.bat, which does everything explained above automatically, producing ten ZIP files ready for distribution. All I need to do is to provide old version of the software in folder named “old”, and modified files in folder named “diff”, run the build.bat, enter couple of parameters and it will spit out ten ZIP files in less than three minutes. Three minutes for full merge/encode/build for all 10 ZIP files instead of three hours (180 minutes), that seems to me like a 60x speed increase/time saving! And chance for errors is minimal! And even if error happens, I can fix it and re-build everything again in three minutes!

Here are couple of screenshots:

Intro/menu screen

Building, building...

Bulding ZIPs

And a log output:

[sun 16.11.2014 @ 18:13:57,89] Started building real-estate-script 2.2 
[sun 16.11.2014 @ 18:14:07,03] Cleaned build directory 
[sun 16.11.2014 @ 18:14:27,91] Merged old and diff versions 
[sun 16.11.2014 @ 18:14:29,83] Copied upgrade version to build directory 
[sun 16.11.2014 @ 18:14:53,10] Encoded project for PHP 5.2 
[sun 16.11.2014 @ 18:15:12,90] Encoded project for PHP 5.3+ 
[sun 16.11.2014 @ 18:15:13,17] Copied skel files 
[sun 16.11.2014 @ 18:15:27,22] Created real-estate-script-2.2-branded-php-5.2.zip 
[sun 16.11.2014 @ 18:15:41,65] Created real-estate-script-2.2-branded-php-5.3.zip 
[sun 16.11.2014 @ 18:15:55,97] Created real-estate-script-2.2-php-5.2.zip 
[sun 16.11.2014 @ 18:16:10,58] Created real-estate-script-2.2-php-5.3.zip 
[sun 16.11.2014 @ 18:16:27,15] Created real-estate-script-2.2-free-trial-php-5.2.zip 
[sun 16.11.2014 @ 18:16:43,70] Created real-estate-script-2.2-free-trial-php-5.3.zip 
[sun 16.11.2014 @ 18:16:45,50] Created real-estate-script-2.2-branded-upgrade-php-5.2.zip 
[sun 16.11.2014 @ 18:16:47,11] Created real-estate-script-2.2-branded-upgrade-php-5.3.zip 
[sun 16.11.2014 @ 18:16:48,74] Created real-estate-script-2.2-upgrade-php-5.2.zip 
[sun 16.11.2014 @ 18:16:50,56] Created real-estate-script-2.2-upgrade-php-5.3.zip 
[sun 16.11.2014 @ 18:16:50,57] Finished building real-estate-script 2.2

I think this is awesome and in future we’ll be releasing new versions more frequently than before! Yay!

CodeIgniter and Datamapper

In PHP, my choice is CodeIgniter framework v.2, a lightweight, zero-configuration, open source OOP MVC framework (Object-oriented programming, model-view-controller framework) which allows you to efficiently split your presentation from logic. And more important, it is really zero-configuration, you can just upload it and start working, everything just works! You can then set/alter configuration later as you work, and their documentation is simply awesome.

Though I know (My)SQL to a certain degree, and sooner or later I’ll make a query that works (more or less efficiently), working with database takes a lot time off my productivity. Therefore I chose Datamapper ORM (Object-relational mapping). Why this and not CodeIgniter’s native models? Well, in college I was simply taught to always make an object one-to-one copy of database table row and this is exactly what Datamapper ORM gives me. I mean, look at this:

//fetch artist by name
$artist = new Artist();
$artist->where('title', 'Primus')->get();

//fetch its albums
$artist->albums->get();
foreach ($artist->albums as $album)
{
 echo "Album: {$album->title} ($album->year)\n";
}

It so easy and natural to work with this. You just need to define a PHP class for each model and set couple of settings inside of it, define relationships (if any) and that’s it! Everything works out of the box. You can of course make custom methods in your model class which can perform certain operations on itself as well as on other (related) models.

I am also exploring Laravel lately, but given the fact that British Columbia Institute of Technology has acquired CodeIgniter and is heavily working on v.3, Laravel might just wait a little bit.

Hello world!

This blog is imagined to be my personal blog about software development and other interesting IT news and tricks. For my personal life you can check my public profiles on popular social networks. Everything written here is my personal opinion, but I’m open for any kind of discussion backed by valid arguments. Please do not expect long and regularly published posts, more like short blurbs published from time to time.