Continuous integration for php
This article was written by my good friend and former colleague fred, working in a team of programmers on a large and complex project that should work 24x7. If someone decides to invite him to the Habr - with pleasure I will send his email by habrpost. Suggestions and comments are welcome, and I undertake to convey the author's answers to the best of my ability.
I had a long thought about launching a CI server for a working project. The base of unit tests is already quite impressive in size, and the number of people in the project has increased slightly. It would be possible to observe how coverage by code tests changes and coding standards are respected. And punish the guilty. Just kidding.
Some time ago, the book Continuous Integration was read . Improving software quality and reducing riskand the article Quality Assurance Tools for PHP , which served as the starting point.
The continuous integration server polls the project repository for changes at some intervals. If changes are found, then he
CruiseControl was chosen as the integration server, along with a php plugin - http://phpundercontrol.org/ .
If you install CruiseControl on a different operating system, the steps are approximately the same: install java, unzip CruiseControl, make scripts for starting and stopping the server.
To start CruiseControl itself, we need to install a Java machine:
and write it in the environment variables:
First, create a user in the system from which CruiseControl will be launched:
Unfortunately, I did not find any fresh .deb packages with CruiseControl, but I haven’t gotten my hands on it yet, so we download the latest version and unpack it into the directory as desired:
and make the owner of our user directory:
We take the shell script from the installation guide for CruiseControl on unix. and save it to the file /etc/init.d/cruisecontrol.
Now you can run CC and verify that it works:
The web interface should be available at http: // yourhostname: 8080 / You can
stop the server accordingly:
We proceed to install the php part.
You probably already have xdebug and pear, but if not:
If you have a lot of code and tests, you should increase the amount of memory allocated to the php process:
Now install the packages for documentation, testing, and code evaluation and phpUnderControl itself:
If you put everything on a separate machine, then do not forget to put all the libraries on which your project depends. At the same time, you can verify that phpunit, phpcs, phpdoc are executed with the parameter sets specified in build.xml.
We make phpUnderControl a CruiseControl plugin, specifying as an argument the directory where the latter is installed:
Open the config.xml configuration file located in the root directory of CruiseControl and replace it with the following:
I moved all the paths to files and directories to variables at the very top of the configuration file, so that if necessary it was easy to fix them in one place.
As a collector, I used ant (it is explicitly specified in config.xml in the / cruisecontrol / project / schedule node ), which is a little familiar to me. If your project already uses phing (which is more logical for php projects than ant), then CruiseControl supports it perfectly.
In the / cruisecontrol / project / publishers node, in addition to processing test results and metrics, you can also send notifications to interested parties via mail / gill in case of unsuccessful builds (possibly successful ones).
A detailed description of the configuration file can be found at CruiseControl Configuration Reference
We pass to the project assembly scenario itself.
All path variables were passed from config.xml
I decided to immediately put build.xml in the repository so that it would be easier to update in the future.
Do not forget to correctly specify the path to it from config.xml (buildfile attribute in the / cruisecontrol / project / schedule / ant node )
Now we upload your project to the / opt / cruisecontrol / projects / yourProjectName / source folder from the repository and run CruiseControl. All!
If there is a warning / notice, Codesniffer does not suppress them and the result is an invalid xml file that CruiseControl cannot read. In general, for any incomprehensible behavior, you can see the log /opt/cruisecontrol/cruisecontrol.sh
As a result of the continuous integration server, we get the following advantages:
I had a long thought about launching a CI server for a working project. The base of unit tests is already quite impressive in size, and the number of people in the project has increased slightly. It would be possible to observe how coverage by code tests changes and coding standards are respected. And punish the guilty. Just kidding.
Some time ago, the book Continuous Integration was read . Improving software quality and reducing riskand the article Quality Assurance Tools for PHP , which served as the starting point.
The continuous integration server polls the project repository for changes at some intervals. If changes are found, then he
- generates documentation in phpdoc format
- checks code against coding standards
- runs tests
- builds metrics from the results of tests and code analysis, as well as the dynamics of changes in these metrics
- notifies everyone interested in case of successful or unsuccessful assembly
CruiseControl was chosen as the integration server, along with a php plugin - http://phpundercontrol.org/ .
Installing CruiseControl on a debian-like machine
If you install CruiseControl on a different operating system, the steps are approximately the same: install java, unzip CruiseControl, make scripts for starting and stopping the server.
To start CruiseControl itself, we need to install a Java machine:
sudo apt-get install sun-java6-bin
and write it in the environment variables:
export JAVA_HOME = / usr / lib / jvm / java-6-sun
First, create a user in the system from which CruiseControl will be launched:
sudo adduser cruisecontrol
Unfortunately, I did not find any fresh .deb packages with CruiseControl, but I haven’t gotten my hands on it yet, so we download the latest version and unpack it into the directory as desired:
s.galkin@java-galkin: / opt $ sudo wget http://sourceforge.net/projects/cruisecontrol/files/CruiseControl/2.8.2/cruisecontrol-bin-2.8.2.zip/download s.galkin@java-galkin: / opt $ sudo unzip cruisecontrol-bin-2.8.2.zip s.galkin@java-galkin: / opt $ sudo mv cruisecontrol-bin-2.8.2 cruisecontrol
and make the owner of our user directory:
s.galkin@java-galkin: / opt $ sudo chown cruisecontrol / opt / cruisecontrol -R
We take the shell script from the installation guide for CruiseControl on unix. and save it to the file /etc/init.d/cruisecontrol.
Now you can run CC and verify that it works:
s.galkin@java-galkin: / opt $ sudo /etc/init.d/cruisecontrol start
The web interface should be available at http: // yourhostname: 8080 / You can
stop the server accordingly:
s.galkin@java-galkin: / opt $ sudo /etc/init.d/cruisecontrol stop
We proceed to install the php part.
You probably already have xdebug and pear, but if not:
sudo apt-get install php5-xdebug sudo apt-cache search php pear
If you have a lot of code and tests, you should increase the amount of memory allocated to the php process:
max_execution_time = 0 memory_limit = 512M
Install php packages
Now install the packages for documentation, testing, and code evaluation and phpUnderControl itself:
pear install PhpDocumentor pear install PHP_CodeSniffer pear channel-discover pear.phpunit.de pear install phpunit / PHPUnit pear channel-discover components.ez.no pear install --alldeps phpunit / phpUnderControl-beta
If you put everything on a separate machine, then do not forget to put all the libraries on which your project depends. At the same time, you can verify that phpunit, phpcs, phpdoc are executed with the parameter sets specified in build.xml.
We make phpUnderControl a CruiseControl plugin, specifying as an argument the directory where the latter is installed:
phpuc install / opt / cruisecontrol
Project setup
Open the config.xml configuration file located in the root directory of CruiseControl and replace it with the following:
I moved all the paths to files and directories to variables at the very top of the configuration file, so that if necessary it was easy to fix them in one place.
As a collector, I used ant (it is explicitly specified in config.xml in the / cruisecontrol / project / schedule node ), which is a little familiar to me. If your project already uses phing (which is more logical for php projects than ant), then CruiseControl supports it perfectly.
In the / cruisecontrol / project / publishers node, in addition to processing test results and metrics, you can also send notifications to interested parties via mail / gill in case of unsuccessful builds (possibly successful ones).
A detailed description of the configuration file can be found at CruiseControl Configuration Reference
We pass to the project assembly scenario itself.
-o HTML: frames: DOM / earthli
-ti '$ {ant.project.name} documentation'
-q
-t $ {project.api.dir}
-d $ {project.code.dir}
"/>
--report = checkstyle
--standard = PEAR
$ {project.code.dir}
"/>
--log-xml $ {project.logs.dir} /phpunit.xml
--log-pmd $ {project.logs.dir} /phpunit.pmd.xml
--log-metrics $ {project.logs.dir} / phpunit.metrics.xml
--coverage-xml $ {project.logs.dir} /phpunit.coverage.xml
--coverage-html $ {project.coverage.dir}
phpucAllTests $ {project.code.dir} / utests / AllTests .php
"/>
All path variables were passed from config.xml
I decided to immediately put build.xml in the repository so that it would be easier to update in the future.
Do not forget to correctly specify the path to it from config.xml (buildfile attribute in the / cruisecontrol / project / schedule / ant node )
Now we upload your project to the / opt / cruisecontrol / projects / yourProjectName / source folder from the repository and run CruiseControl. All!
Existing problems
If there is a warning / notice, Codesniffer does not suppress them and the result is an invalid xml file that CruiseControl cannot read. In general, for any incomprehensible behavior, you can see the log /opt/cruisecontrol/cruisecontrol.sh
Total
As a result of the continuous integration server, we get the following advantages:
- all developers are notified in a timely manner of a failed build
- dynamics of changes in the number of tests
- dynamics of changes in the percentage of code covered by tests
- analysis of test coverage for specific classes
- violation of coding standards
- up-to-date documentation on internal api
- static code analysis: too long methods, too complicated conditional logic, ...