Thursday, October 02, 2008

How to you handle Revision Control for eZ Publish Projects?

Ch-ch-changes (by TW Collins)
Revision control systems (RCS) play an essential part of any software development process. One reason for using a RCS is to enable applications to be rolled back and deployed from a known point in time. Due to the nature of eZ publish it's difficult to capture all changes in the RCS and this often leads to the requirement of manual adjustments when changes are deployed.

An eZ publish project is made up of a number of elements that are stored either on the file system or in the database. The database not only stores the site's content but also a number of "configuration" items, such as roles & policies, content class & workflow definitions, RSS feed configurations and URL translations (I'm sure there are more).

Another scenario where this feature will pose an issue is if you use a node override to utilise a specific template for a particular node. In this case the entry in override.ini relies on a specific node_id to link the template to the node. It's unlikely that the node_id of the development system will match the live system and the deployment will fail. Roles and policies will also suffer from this issue as they are reliant on content e.g. applied to a specific node subtree or applied to a user group.

These configuration items play an important role in a correctly functioning eZ Publish site. The reliance of configuration information stored in the database makes it difficult to capture this information in revision control in a way it can be automatically deployed or rolled back from the RCS.

Earlier this year Jérôme Renard published an great article entitled Using Subversion with eZ Publish that touched on this point, suggesting that some tables can be exported from the database and the resulting dump included in the RCS. While this would work ,it relies on the developer remembering to do it when changes are committed. It aslo means that the specific configuration changes are not captured in the RSC with any associated file changes. i.e. It's not easy to look at the diff from the previous commit and see what changed.

I suspect that eZ Publish is not the only platform effected by this issue. While not the exact problem, Ruby on Rails solves a similar issue though use of migrations where database changes for both the update and reverse it are stored in files and applied programatically.

How to you address this issue this for your eZ Publish projects? Database dumps? The eZ package system? Home grown scripts? Something else?


  1. A very interesting question/discussion, Bruce. I've been wondering myself for quite some time now how other eZ developers handle versioning.

    Here's a quick overview of how we do it:

    First, we only version-control the extensions of an installation. I've heard that some people also version the var/ and settings/ folders, but we've found this to work best for us.

    This does, of course, leave out roles and permissions, content classes and workflow definitions. Since these rarely change once they are set up, we've opted for documenting the setup of these in the INSTALL documentation of each extension.

    Our development process varies depending on whether we are fixing a bug/adding a minor feature, or developing a new site/extensive functionality. For the latter, we usually setup a local replica of the site in question, either by copying the eZ installation, or setting up the same eZ Publish version. We also copy the database to ensure we have the same data structure. For minor fixes, we checkout the extension in question to a generic, local eZ install, do the changes, and commit it back.

    Whenever we do something node-specific, we store the node ID's in INI files so they can be changed to suit the environment. This doesn't work very well with the default override system, so we tend to create our own module views so we can control how the templates are used.

    I'm not saying our way is The Right Way - on the contrary; I'm very interested in hearing what others have to say on this issue.


    Eirik Johansen


    Keeping environment-specific INI files and ignoring the original in the RCS can help a human or a script build an env:


    site.ini.append.php (ignored)

    A developer can then use their own site.ini, but commit changes to the different env INIs.

    Likewise, node IDs can be put into env-specific custom INIs, and env-specific override INI files could be used too.

    You could combine the two as part of your build scripts, so that each setting in your custom INI has 3 values - dev, staging, live (e.g NewsFolderID=56;82;93) and your build script replaces that setting in your override (e.g Match[node]={NewsFolderID}) with the env-specific value.

    No easy answer on the db front... but I wish there was one!


  3. Website sources are stored as eZ extension. Each extension is in SVN repository. Just needed to be enabled in global settings.

    Each developer has well-prepared linux VM with eZ and MySQL with initial DB (clean for the first time). Also, staging VM has the same config.

    Adding content classes/objects is done on staging DB. When something significant added - developer uses sync shell script and gets latest version of DB. After the milestone the DB is uploaded to production server.

    SVN repository always has development version committed, so any developer can checkout project extension(s) and have site ready to run. This concerns project settings.

    For deployment SVN is used: just usual checkout from specified repository URL as a step of installation/deployment shell script. Script then uses "undocumented feature" of eZ settings files - any content can be appended to the end of settings files and it is OK. So, script appends deploy-target-specific data to specified files, like DB info, debug=off, etc..