Let's setup Continuous Integration server together

We have wondered about the CI for a long time already and finally, the idea became a reality and we have begun the process of implementation. We want to share our experience, hence we decided to write an article about Continuous Integration (CI).

Continuous Integration (CI) is the principle or software development practice, which is aimed to simplify and standardize the development process. When you have one or two developers in your team, then is not that difficult to build process manually. But with the increase in staff it becomes difficult to control development processes manually, and in some moments - it is even impossible. Therefore there is a need to automate certain business processes, where Continuous Integration Server can help.

It can help you solve following tasks:

  • Automatic code quality check
  • Launching and testing migrations
  • Check the installation of libraries (in this case, bundles)
  • Load testing fixture (test data)
  • The launch of automated tests.

After the assembly - CI can post messages on the results of execution.

During CI server selection process have checked several options for CI servers: jenkins, phpci, travis. But in the end we settled on phpci. Actually about it and will talk further.

Phpci - is an open source project, written in php and for php. In fact it is a normal php-project, which is able to perform console commands and process the results of their work. Inside phpci has several plug-ins by default, but it also has the ability to add own plug-ins. To install phpci it is necessary to download the archive from the official website of the project phptesting.org or clone a project by link github.com/Block8/PHPCI. Then you need to configure virtual hosts for the project and run the installation from the console. The installation process itself is very well explained on the official website.

During the process of learning and adjustment, we realized that we only need to use some plugins from the entire spectrum provided. For example:

  • PhpCodeSniffer - plug-in for checking the quality of coding
  • PhpLoc - plug-in for the evaluation of the written code, it has some interesting metrics that can be tracked.
  • PhpDocblockChecker - plug-in for checking written PhpDocs
  • Lint - plug-in to detect errors in the code, mainly syntax
  • SlackNotify - sending messages to Slack. This is very convenient because we use it constantly in our work.
  • Composer - unreplacable plug-in, because most of our projects are written in Symfony2

Composer - is plug-in that allows you to install the necessary dependencies of the project.

In phpci it is called as a command line utility, so it needs to be installed separately. The installation process itself is explained on the page https://getcomposer.org/download/. After installing the utility you can use in phpci. It should be noted that the Composer must be able to be called anywhere by using the "composer" command. Other utilities must be called in the same way.

PhpDocblockChecker - is a command line utility as well, although it is not installed separately but together with the whole project. To install it, you only need to execute the command "composer install" in the folder with the project phpci. The code will be installed to the folder with the plug-ins, and the command for PhpDocblockChecker  will be added to the folder "bin".

PhpLoc - is a plug-in for static code analysis. After the console utility run it will return results with metrics throughout the code. The process of installing the plugin is by the link https://github.com/sebastianbergmann/phploc.

In the future we will add the plug-ins for automated testing and plug-in to work with Symfony2 commands.

After we installed and configured phpci and added all the necessary plug-ins, we can customize our build.

To set up the project, it should be added to phpci first. The form for adding the project contains fields for the name of the project, links to the repository, additional information, and another interesting field "Private key to use to access repository (leave blank for local and / or anonymous remotes)". This is the key that should be added to the repository so phpci could clone him.

After adding the project with CI - the assembly itself needs to be set up. There are two possibilities to do this , either we add a configuration file in the project or add the same settings in the "PHPCI build config for this project", which is in the form of adding the project. We decided to go with adding the file to the project.

The data in the file must be in the format yml. It's easy to understand, but, for clarity, we provide an example of the file.



   - "Vendor"

   - "Bin"

   - "App"



   action: "install"

   prefer_dist: true



   path: "src"

   standard: "/rulers.xml"

   csslint_path: "src"


   directory: "src"


      allowed_warnings: 10

lint: ~

Section “setup” - is installation setup of the project, so far we have  there only setting for the installation dependencies: "action:" install”" - this is an indication which command you need to run for the composer, "prefer_dist: true" - is an indication where you need to install dependency from - source (the default) or packegist.org. As it turned out, the second option runs faster since composer caches previously installed packages and next time installs it much more faster.

Section "test" - is indication for plug-ins. Each plug-in has its own configuration, the information about them can be found on the official website of the project.

Then goes the most interesting part. CI - рow it works? In principle, server should build the project automatically when a particular event occurs. In our case, this event is the creation of pull request. Then phpci should build the project out of particular branch, test it and if all goes well - the developer can merge it into the main branch.

Unfortunately, "out of the box", we were not able to adjust the desired behavior of the system. Therefore we have created a copy of the project, updated the logic of work, and,  of course, created a pull request to the official repository.

So how it works for us now. Before start developer creates a separate branch of "dev" branch. Since the source code of our projects is on bitbucket.org it can be done through the system interface or by the old fashioned way using the command "git checkout -b branch_name". After all necessary changes have been made, developer needs to merge branch to "dev" branch, but before the merge it is necessary to ensure that the existing functionality is not broken, and the new added works correctly. Here CI starts to operate, it runs the static testing of code using a several of console tools, tests the assembly by a composer and executs the automated tests using PhpUnit. To do this - bitbucket has so-called hooks. These are additional steps that are performed automatically while changes are sent to bitbucket by command "git push" or while creation of a pull requests. The result of the hooks are those events for which phpci begins to collect and test a project.

After all work we have done - we finally have a Continuous integration server set up. Of course, this is only the beginning, and we still have to add the additional plug-ins, most likely will have to write a part of it by ourselves, but it is already a good start.

We hope that our experience will help you to automate your processes.

Best wishes,

Mind Team.

Published at:12.11.2015