Working in the Internal Projects department at Epiphany, we build tools for the rest of the company to help them in their work. Due to the fast-changing nature of the arena in which we operate, the way they work is constantly evolving and consequently the tools which we build for them must be able to change rapidly too.
Working in the Internal Projects department at Epiphany, we build tools for the rest of the company to help them in their work. Due to the fast-changing nature of the arena in which we operate, the way they work is constantly evolving and consequently the tools which we build for them must be able to change rapidly too. In order to be able to meet this demand for change whilst still delivering quality software, we have adopted a strategy of continuous integration and deployment. What this means in practice is that our development versions of the software should never be too far away from the stable, production version and that by automating as much of the process as possible we can make it relatively painless. We implement this process using a combination of Git, Apache Ant and Jenkins, plus associated utilities for performing the build (PHPUnit, PHPCheckStyle, PHP Mess Detector.) The development server holds a central repository of the code which is “stable” i.e. should build with no problems and is theoretically safe to deploy (features are permitted to be incomplete but they should not be broken.) Developers operate on a clone of the central repository in their home directory. If they are working on a large change to the code, they’ll create a new branch in order to be able to return to the original code if any minor changes occur before the major one is complete, but small changes can be made directly to the master. When a feature is complete, the developer will merge the branch back into the master if necessary, then push the changes up to the central repository. Jenkins, the build server, will notice changes to the central repository and automatically trigger a build. If the build passes, a post-build action will tag the revision in Git with the build number and date and then push it to a remote repository on the production server. Having got the latest build onto the production server we then use post-commit hooks in Git to check the code out into a directory under the web root. For smaller, less critical, applications we make this checkout run directly into the live site thus updating it automatically every time a build passes. For critical code, however, we’re not quite brave enough to do that so the checkout is performed into a beta or staging site. This way we can check the update in the production environment for any issues which may arise, and we can also send new features for review with the project stakeholders without releasing them to the entire user base. To deploy from staging to live, we use a short Perl script which exports the code for a build into its own directory then uses symbolic links to point the live site at the latest directory. Using this technique makes it extremely straightforward to switch between versions, so if there is a problem with the latest version of the application we can swiftly revert to the previous one. This is important as users of the system require it to be available at all times. This is our first attempt at a continuous deployment process and it seems to be working pretty well so far. No doubt there are improvements which could be made to the process and we may find we need to change it down the line but it’s certainly an improvement on the old ways.