Continuous Integration with Jenkins and Drupal 7

Continuous Integration with Jenkins and Drupal 7

As part of the Knowledge Lab at Cocomore on 2 September, 2011, I outlined how to use Jenkins to implement Continuous Integration for a Drupal-based project. The basic building blocks for the demonstration included Jenkins, a demo Drupal project, and its automatic update from the SVN version control system, which triggers each run of SimpleTest. I will describe the primary steps to this process here.

Basic Installation

There are fully prepared Jenkins packages available for download for the most popular Linux distributions, including the Debian server version I used. The Jenkins project even maintains a repository which blends seamlessly into the software management. All the necessary commands are described on the Jenkins download page; with them, installing the base system is simply an “apt-get install jenkins” away.

Of course, since we want to test a Drupal system, our machine also needs a Web server (Apache), PHP, and a database (MySQL). Installing Ant is also useful, since it provides a good way to automate tasks and is very well supported by Jenkins.

Configuration

The next step is to create a new Job in Jenkins for testing our project. The “Build a free-style software project” option is the recommended setting for an Ant-based project like this.

Create a new job in Jenkins

On the configuration page, there are numerous settings to customize the job, according to your needs. For example, you can configure which version control system to use. CVS and SVN support are included in the Jenkins default installation, but there are easily-installed Jenkins plugins available for numerous other systems such as Git, Mercurial, or Bazaar. In this example, we are using SVN.

We need to add the repository URL (including path) to allow Jenkins to find our source code. We also need to configure what should trigger a build. For easy setup, it makes sense to either start the build at fixed intervals, or have Jenkins make periodic checks for changes in the repository and begin build execution after changes. We’ll choose the latter option and, for this example, the code in the “Schedule” field is set to check the repository every two minutes. It’s also useful that Jenkins examines not only the version of the “direct” project code, but also any linked dependencies via svn:externals.

Configure SVN in Jenkins

Now that Jenkins can find the source code, we need to configure what should happen during a build. We have chosen to create an Ant-based target, so we create a series of steps for our build, as Ant targets, which are executed in sequence.

Build processes in Selenium configured with Ant targets

We have yet to define what to do with the results of the build. We want to configure SimpleTest to write its output in JUnit XML format, so we select the JUnit plugin and enter the location our SimpleTest output will be found.

Post-build actions in Jenkins.

Here’s the relevant excerpt of the Ant target which runs the SimpleTests. In this example, it runs all tests in the group, “Demo”:

   target name="run_simpletests">
  [...]
   <exec dir="${basedir}/htdocs"
    executable="php"
    failonerror="true">
    arg line="scripts/run-tests.sh --php /usr/bin/php --url http://demo.debiserv/
      $--xml {basedir}/build/logs/simpletest Demo"/>
   </exec>
  </target>
 

The example below shows a very simple “Dummy” SimpleTest, which can be switched back and forth between returning “test successful” and “test failed”.

<?php
    
class DemoModuleTestCase extends DrupalWebTestCase {

      public static function
getInfo() {
       return array(
      
'name' => 'Demo Module tests',
      
'description' => 'Test the demo module.',
      
'group' => 'Demo',
        );
      }
   
      public function
testDummyTest() {
      
$value = true;
      
//$value = false;
      
$this->assertTrue($value, 'The value is true.');
      }
     }

?>
 

Jenkins build historyHere, if we look at the “Build History” block, we can see the results summary for recent test commits. The first was set to trigger a SimpleTest failure. Jenkins recognized a change in SVN, which triggered running build #34. The yellow ball indicates a build which completed, but a test failed. A subsequent commit to SVN triggered build #35; the blue ball indicates that the build and test were successful.

You can easily configure Jenkins to send notifications, via RSS or email, whenever the status of a project changes, so your development team is immediately made aware whenever any code changes cause a test to fail.

Conclusion: Continuous integration with Jenkins is useful

In conclusion, continuous integration can be implemented with Jenkins for a Drupal project. It is useful to formulate the steps as Ant targets; these targets can also be used for setting up development environments, so the time taken to write the automation is spent once, with continuous dividends throughout the life of your project. Drupal’s built-in SimpleTest framework can be a step in the project build process and further integrate its output with JUnit-compatible post-processing plug-ins. Jenkins notification features help keep developers up-to-date on the status of the project. With a little configuration, this can produce a complete solution.

PS: This basic demonstration of Jenkins did not cover the issues of security and authentication. As you’d expect, Jenkins supports users and access rights. On real installations such configuration should be considered mandatory, even if the system is in your internal network.

 

About Cocomore