Wednesday, October 21, 2015

Continous integration with PHP and Jenkins


Continuous integration (CI) is a development practice which allows testing, building and checking the quality of the application in automated way without manual developer intervention. It requires developers to integrate code into a shared repository several times a day or every commit/merge to the given branch of the repository. Each check-in is then verified by an automated build, allowing teams to detect problems early.

While PHP Continuous Integration (PHPCI) does not require the the code compilation as
build” one can understand the set of task like testing and quality checks which are performed in timely manner or when the certain conditions are met.
PHPCI can be performed on Jenkins Server. The detailed description of jenkins server configuration in is presented here. PHPCI requires PHing package which can be provided into application by Composer.

“PHing Is Not GNU make” is a PHP project build tool based on Apache Ant. It uses simple XML build files which make it an easy-to-use and highly flexible build framework.
Typical PHPCI configuration allows you to test every commit your team decided to merge to the “master” or “stage” branch. It makes passes all your unit tests and check if the code meets your standards.

The build is configured in build.xml file which is quite self-explanatory. Other xml files may be required to configure so called “targets” - the task which are performed every build. The best way to provide php related targets is to install them by the composer. This way no alterations on Jenkins Server are needed:

In the example configurarion presented on GitHub  the following extensions are installed:

Phing: (described above) - the tool chosen to build and manage the project
PHPUnit - provides the unit tests framework.
CodeSniffer - provides syntax check for the project.
PHPMD - detects possible problems and complexity throughout the code.
PHPLoc - does a summary of how much lines of code, classes, etc the code has.
PHPDepend - is used to analyze dependencies between the different modules of the application.
PHPDox - php documentation generator
PHPloc - quickly measuring the size and analyzing the structure of a PHP project.
Interpretation of the build results

Each build is described by two basic icons which are “Status” (S) and “Weather” (W). Every successful build is indicated by green light in the status column. The problem with build is indicated by red light. The weather status shows the progressive status of the several last builds. The cloudy weather means that build is not stable and several last builds might have been unsuccessful. Sunny weather indicates stable projects.

Even successful build is worth analyzing by looking at two charts: Abstraction Instability Chart and Overview Pyramid:

The Abstraction Instability Chart chart as it is generated by PHPDepend is based on the whitepaper OO Design Quality Metrics. It shows the quality of design in the terms of extensibility, reusability and maintainability. All these facts are influenced by the inter-package dependencies and the package abstraction.
The Overview Pyramid is used to visualize a complete software system in a really compact manner. Therefore it collects a set of metrics from the categories like:  Inheritance, Coupling and Size & Complexity, and puts them into relation. The Overview Pyramid provides a simple and size independent way to get a first impression of a software system, and this without an expensive source code analysis. Thus the Overview Pyramid is an effective tool for a first cost estimate for an unknown system.
If the application is built on the top of the framework the Abstraction Instability Chart and Overview Pyramid usually shows more relevant results for the framework then to our code. To limit the results to code developed in your team it is possible to limit the project base dir in build.xml file.
The detailed metrics are described here.
Code Complexity warnings and Duplicate Code warnings are available after clicking on the build link.
If the build fails one can be interested what is the root cause of the red light in jenkins. This can be done by accessing the build console. The console output shows detailed description of how the build was performed, which unit tests failed, the PHP warnings and notices and so on.

Setting up Jenkins

In case of the build problem the debugging on local machine may be required. On the local machine the build can be simulated by running phing from the command line. Being in the root directory of app which contain phing installed by composer you can run:
The PHing will perform exactly the same build process as on the Jenkins server.
Developer can also install Jenkins locally in order to test continuous integration on development machine before the project is deployed to continuous integration server:

apt-get install jenkins
# Prepare jenkins command line tool
wget http://localhost:8080/jnlpJars/jenkins-cli.jar
# install jenkins modules
java -jar jenkins-cli.jar -s http://localhost:8080 install-plugin checkstyle cloverphp dry htmlpublisher jdepend plot pmd violations xunit git bitbucket
java -jar jenkins-cli.jar -s http://localhost:8080 safe-restart
sudo apt-get install curl
# install the template
java -jar jenkins-cli.jar -s http://localhost:8080 safe-restart

To create Jenkins job in GUI go to Jenkins then choose:

  1. New Item -> Freestyle project -> git
  2. Add jenkins credential (login and private key)
  3. Check "Build when a change is pushed to BitBucket"
  4. Add build Step "Execute shell" and paste “vendor/bin/phing -logger phing.listener.NoBannerLogger"
  5. Save Job

Other Relevant Information

PHP Continuous integration benefits a lot from the unit tests. To get the best results team need to remember to keep level of the unittest close to 100% or above 100% coverage.

Setting up PHing configuration for the new project can be as easy as copying the build.xml file from existing project. Developer need to remember to add required targets to the composer.json file and properly bootstrap the PHPUnit and PHing. Also the proper permission need to be set in the project so temporary “build” directory can be created by Jenkins.
Post a Comment