{"id":2095,"date":"2018-05-17T16:20:42","date_gmt":"2018-05-17T14:20:42","guid":{"rendered":"http:\/\/miroslaw.borodziuk.eu\/?p=2095"},"modified":"2018-05-22T14:37:27","modified_gmt":"2018-05-22T12:37:27","slug":"ci-cd-projektow-php-na-jenkinsie-ciagla-integracja","status":"publish","type":"post","link":"http:\/\/miro.borodziuk.eu\/index.php\/2018\/05\/17\/ci-cd-projektow-php-na-jenkinsie-ciagla-integracja\/","title":{"rendered":"CI\/CD projekt\u00f3w PHP na Jenkinsie \u2013 Ci\u0105g\u0142a Integracja"},"content":{"rendered":"<p>W tym artykule poszerzymy plik <em>Anta<\/em> build.xml o testy jednostkowe przeprowadzane przy pomocy PHPUnit.<\/p>\n<p><!--more--><\/p>\n<p>Przed uruchomienie test\u00f3w jednostkowych powinni\u015bmy sprawdzi\u0107 czy kod PHP nie zawiera b\u0142\u0119d\u00f3w sk\u0142adniowych. Kod poni\u017cej implementuje cel, kt\u00f3ry u\u017cywa zadania <code>&lt;apply&gt;<\/code> Apache Ant do wywo\u0142ania PHP lint checker (<code>-l<\/code>) dla ka\u017cdego pliku z kodem \u017ar\u00f3d\u0142owym w katalogach <code>src<\/code> i <code>tests<\/code>. Zadanie <code>&lt;apply&gt;<\/code> dzia\u0142a tak jak <code>&lt;exec&gt;<\/code> ale mo\u017ce dzia\u0142a\u0107 na wielu plikach przekazanych jako<code> &lt;fileset&gt;<\/code>.<\/p>\n<pre class=\"lang:sh decode:true \">&lt;target name=\"lint\"\r\n  unless=\"lint.done\"\r\n  description=\"Perform syntax check of sourcecode files\"&gt;\r\n  &lt;apply executable=\"php\" taskname=\"lint\"&gt;\r\n    &lt;arg value=\"-l\" \/&gt;\r\n\r\n    &lt;fileset dir=\"${basedir}\/src\"&gt;\r\n      &lt;include name=\"**\/*.php\" \/&gt;\r\n      &lt;modified \/&gt;\r\n    &lt;\/fileset&gt;\r\n\r\n    &lt;fileset dir=\"${basedir}\/tests\"&gt;\r\n      &lt;include name=\"**\/*.php\" \/&gt;\r\n      &lt;modified \/&gt;\r\n    &lt;\/fileset&gt;\r\n  &lt;\/apply&gt;\r\n\r\n  &lt;property name=\"lint.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>Do przeprowadzania test\u00f3w jednostkowych wykorzystamy PHPUnit. Plik konfiguracyjny <code>phpunit.xml.dist<\/code> wygl\u0105da nast\u0119puj\u0105co:<\/p>\n<pre class=\"lang:sh decode:true\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;phpunit bootstrap=\"tests\/bootstrap.php\"\r\nbackupGlobals=\"false\"\r\nbackupStaticAttributes=\"false\"\r\nstrict=\"true\"\r\nverbose=\"true\"&gt;\r\n\r\n&lt;testsuites&gt;\r\n&lt;testsuite name=\"ProjectName\"&gt;\r\n&lt;directory suffix=\"Test.php\"&gt;tests\/unit\/&lt;\/directory&gt;\r\n&lt;directory suffix=\"Test.php\"&gt;tests\/integration\/&lt;\/directory&gt;\r\n&lt;\/testsuite&gt;\r\n&lt;\/testsuites&gt;\r\n\r\n&lt;logging&gt;\r\n&lt;log type=\"coverage-html\" target=\"build\/coverage\"\/&gt;\r\n&lt;log type=\"coverage-clover\" target=\"build\/logs\/clover.xml\"\/&gt;\r\n&lt;log type=\"coverage-crap4j\" target=\"build\/logs\/crap4j.xml\"\/&gt;\r\n&lt;log type=\"junit\" target=\"build\/logs\/junit.xml\" logIncompleteSkipped=\"false\"\/&gt;\r\n&lt;\/logging&gt;\r\n\r\n&lt;filter&gt;\r\n&lt;whitelist addUncoveredFilesFromWhitelist=\"true\"&gt;\r\n&lt;directory suffix=\".php\"&gt;src&lt;\/directory&gt;\r\n&lt;exclude&gt;\r\n&lt;file&gt;src\/bootstrap.php&lt;\/file&gt;\r\n&lt;\/exclude&gt;\r\n&lt;\/whitelist&gt;\r\n&lt;\/filter&gt;\r\n&lt;\/phpunit&gt;<\/pre>\n<p>Wywo\u0142anie phpunit bez argument\u00f3w w katalogu projektu (tam gdzie znajduje si\u0119 plik <code>phpunit.xml.dist<\/code>) spowoduje uruchomienie PHPUnit dok\u0142adnie w taki spos\u00f3b jak okre\u015blono w konfiguracji przedstawionej powy\u017cej. Teraz mo\u017cemy doda\u0107 cel do pliku <code>build.xml<\/code>, kt\u00f3ry wywo\u0142a PHPUnit do przeprowadzenia test\u00f3w jednostkowych.<\/p>\n<pre class=\"lang:sh decode:true \">&lt;target name=\"phpunit\"\r\nunless=\"phpunit.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Run unit tests with PHPUnit\"&gt;\r\n&lt;exec executable=\"${phpunit}\" resultproperty=\"result.phpunit\" taskname=\"phpunit\"&gt;\r\n&lt;arg value=\"--configuration\"\/&gt;\r\n&lt;arg path=\"${basedir}\/build\/phpunit.xml\"\/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpunit.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpunit-no-coverage\"\r\nunless=\"phpunit.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Run unit tests with PHPUnit (without generating code coverage reports)\"&gt;\r\n&lt;exec executable=\"${phpunit}\" failonerror=\"true\" taskname=\"phpunit\"&gt;\r\n&lt;arg value=\"--configuration\"\/&gt;\r\n&lt;arg path=\"${basedir}\/build\/phpunit.xml\"\/&gt;\r\n&lt;arg value=\"--no-coverage\"\/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpunit.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>Przy okazji dodajmy dwa inne cele. <em>Clean<\/em> to target odpowiedzialny za czyszczenie (usuwanie) artefakt\u00f3w wyprodukowanych przez poprzedni build. Ten cel uruchamiany jest przez target <em>prepare<\/em>, ale mo\u017ce by\u0107 tak\u017ce wywo\u0142ywany niezale\u017cnie.<\/p>\n<pre class=\"lang:sh decode:true\">&lt;target name=\"clean\"\r\nunless=\"clean.done\"\r\ndescription=\"Cleanup build artifacts\"&gt;\r\n&lt;delete dir=\"${basedir}\/build\/api\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/coverage\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/logs\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/pdepend\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/phpdox\"\/&gt;\r\n&lt;property name=\"clean.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n<\/pre>\n<p>Cel<em> prepare<\/em> uruchamia target <em>clean<\/em> i tworzy katalogi, w kt\u00f3rych PHPUnit zapisuje logi i raporty.<\/p>\n<pre class=\"lang:sh decode:true \">&lt;target name=\"prepare\"\r\nunless=\"prepare.done\"\r\ndepends=\"clean\"\r\ndescription=\"Prepare for build\"&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/api\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/coverage\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/logs\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/pdepend\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/phpdox\"\/&gt;\r\n&lt;property name=\"prepare.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>Ca\u0142a zawarto\u015b\u0107 build.xml:<\/p>\n<pre class=\"lang:sh decode:true \">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;project name=\"name-of-project\" default=\"full-build\"&gt;\r\n&lt;!-- By default, we assume all tools to be on the $PATH --&gt;\r\n&lt;property name=\"pdepend\" value=\"pdepend\"\/&gt;\r\n&lt;property name=\"phpcpd\" value=\"phpcpd\"\/&gt;\r\n&lt;property name=\"phpcs\" value=\"phpcs\"\/&gt;\r\n&lt;property name=\"phpdox\" value=\"phpdox\"\/&gt;\r\n&lt;property name=\"phploc\" value=\"phploc\"\/&gt;\r\n&lt;property name=\"phpmd\" value=\"phpmd\"\/&gt;\r\n&lt;property name=\"phpunit\" value=\"phpunit\"\/&gt;\r\n\r\n&lt;!-- Use this when the tools are located as PHARs in ${basedir}\/build\/tools\r\n&lt;property name=\"pdepend\" value=\"${basedir}\/build\/tools\/pdepend.phar\"\/&gt;\r\n&lt;property name=\"phpcpd\" value=\"${basedir}\/build\/tools\/phpcpd.phar\"\/&gt;\r\n&lt;property name=\"phpcs\" value=\"${basedir}\/build\/tools\/phpcs.phar\"\/&gt;\r\n&lt;property name=\"phpdox\" value=\"${basedir}\/build\/tools\/phpdox.phar\"\/&gt;\r\n&lt;property name=\"phploc\" value=\"${basedir}\/build\/tools\/phploc.phar\"\/&gt;\r\n&lt;property name=\"phpmd\" value=\"${basedir}\/build\/tools\/phpmd.phar\"\/&gt;\r\n&lt;property name=\"phpunit\" value=\"${basedir}\/build\/tools\/phpunit.phar\"\/&gt; --&gt;\r\n\r\n&lt;!-- Use this when the tools are managed by Composer in ${basedir}\/vendor\/bin\r\n&lt;property name=\"pdepend\" value=\"${basedir}\/vendor\/bin\/pdepend\"\/&gt;\r\n&lt;property name=\"phpcpd\" value=\"${basedir}\/vendor\/bin\/phpcpd\"\/&gt;\r\n&lt;property name=\"phpcs\" value=\"${basedir}\/vendor\/bin\/phpcs\"\/&gt;\r\n&lt;property name=\"phpdox\" value=\"${basedir}\/vendor\/bin\/phpdox\"\/&gt;\r\n&lt;property name=\"phploc\" value=\"${basedir}\/vendor\/bin\/phploc\"\/&gt;\r\n&lt;property name=\"phpmd\" value=\"${basedir}\/vendor\/bin\/phpmd\"\/&gt;\r\n&lt;property name=\"phpunit\" value=\"${basedir}\/vendor\/bin\/phpunit\"\/&gt; --&gt;\r\n\r\n&lt;target name=\"full-build\"\r\ndepends=\"prepare,static-analysis,phpunit,phpdox,-check-failure\"\r\ndescription=\"Performs static analysis, runs the tests, and generates project documentation\"\/&gt;\r\n\r\n&lt;target name=\"full-build-parallel\"\r\ndepends=\"prepare,static-analysis-parallel,phpunit,phpdox,-check-failure\"\r\ndescription=\"Performs static analysis (executing the tools in parallel), runs the tests, and generates project documentation\"\/&gt;\r\n\r\n&lt;target name=\"quick-build\"\r\ndepends=\"prepare,lint,phpunit-no-coverage\"\r\ndescription=\"Performs a lint check and runs the tests (without generating code coverage reports)\"\/&gt;\r\n\r\n&lt;target name=\"static-analysis\"\r\ndepends=\"lint,phploc-ci,pdepend,phpmd-ci,phpcs-ci,phpcpd-ci\"\r\ndescription=\"Performs static analysis\" \/&gt;\r\n\r\n&lt;!-- Adjust the threadCount attribute's value to the number of CPUs --&gt;\r\n&lt;target name=\"static-analysis-parallel\"\r\ndescription=\"Performs static analysis (executing the tools in parallel)\"&gt;\r\n&lt;parallel threadCount=\"2\"&gt;\r\n&lt;sequential&gt;\r\n&lt;antcall target=\"pdepend\"\/&gt;\r\n&lt;antcall target=\"phpmd-ci\"\/&gt;\r\n&lt;\/sequential&gt;\r\n&lt;antcall target=\"lint\"\/&gt;\r\n&lt;antcall target=\"phpcpd-ci\"\/&gt;\r\n&lt;antcall target=\"phpcs-ci\"\/&gt;\r\n&lt;antcall target=\"phploc-ci\"\/&gt;\r\n&lt;\/parallel&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"clean\"\r\nunless=\"clean.done\"\r\ndescription=\"Cleanup build artifacts\"&gt;\r\n&lt;delete dir=\"${basedir}\/build\/api\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/coverage\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/logs\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/pdepend\"\/&gt;\r\n&lt;delete dir=\"${basedir}\/build\/phpdox\"\/&gt;\r\n&lt;property name=\"clean.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"prepare\"\r\nunless=\"prepare.done\"\r\ndepends=\"clean\"\r\ndescription=\"Prepare for build\"&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/api\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/coverage\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/logs\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/pdepend\"\/&gt;\r\n&lt;mkdir dir=\"${basedir}\/build\/phpdox\"\/&gt;\r\n&lt;property name=\"prepare.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"lint\"\r\nunless=\"lint.done\"\r\ndescription=\"Perform syntax check of sourcecode files\"&gt;\r\n&lt;apply executable=\"php\" taskname=\"lint\"&gt;\r\n&lt;arg value=\"-l\" \/&gt;\r\n\r\n&lt;fileset dir=\"${basedir}\/src\"&gt;\r\n&lt;include name=\"**\/*.php\" \/&gt;\r\n&lt;modified \/&gt;\r\n&lt;\/fileset&gt;\r\n\r\n&lt;fileset dir=\"${basedir}\/tests\"&gt;\r\n&lt;include name=\"**\/*.php\" \/&gt;\r\n&lt;modified \/&gt;\r\n&lt;\/fileset&gt;\r\n&lt;\/apply&gt;\r\n\r\n&lt;property name=\"lint.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phploc\"\r\nunless=\"phploc.done\"\r\ndescription=\"Measure project size using PHPLOC and print human readable output. Intended for usage on the command line.\"&gt;\r\n&lt;exec executable=\"${phploc}\" taskname=\"phploc\"&gt;\r\n&lt;arg value=\"--count-tests\" \/&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;arg path=\"${basedir}\/tests\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phploc.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phploc-ci\"\r\nunless=\"phploc.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Measure project size using PHPLOC and log result in CSV and XML format. Intended for usage within a continuous integration environment.\"&gt;\r\n&lt;exec executable=\"${phploc}\" taskname=\"phploc\"&gt;\r\n&lt;arg value=\"--count-tests\" \/&gt;\r\n&lt;arg value=\"--log-csv\" \/&gt;\r\n&lt;arg path=\"${basedir}\/build\/logs\/phploc.csv\" \/&gt;\r\n&lt;arg value=\"--log-xml\" \/&gt;\r\n&lt;arg path=\"${basedir}\/build\/logs\/phploc.xml\" \/&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;arg path=\"${basedir}\/tests\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phploc.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"pdepend\"\r\nunless=\"pdepend.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Calculate software metrics using PHP_Depend and log result in XML format. Intended for usage within a continuous integration environment.\"&gt;\r\n&lt;exec executable=\"${pdepend}\" taskname=\"pdepend\"&gt;\r\n&lt;arg value=\"--jdepend-xml=${basedir}\/build\/logs\/jdepend.xml\" \/&gt;\r\n&lt;arg value=\"--jdepend-chart=${basedir}\/build\/pdepend\/dependencies.svg\" \/&gt;\r\n&lt;arg value=\"--overview-pyramid=${basedir}\/build\/pdepend\/overview-pyramid.svg\" \/&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"pdepend.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpmd\"\r\nunless=\"phpmd.done\"\r\ndescription=\"Perform project mess detection using PHPMD and print human readable output. Intended for usage on the command line before committing.\"&gt;\r\n&lt;exec executable=\"${phpmd}\" taskname=\"phpmd\"&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;arg value=\"text\" \/&gt;\r\n&lt;arg path=\"${basedir}\/build\/phpmd.xml\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpmd.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpmd-ci\"\r\nunless=\"phpmd.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Perform project mess detection using PHPMD and log result in XML format. Intended for usage within a continuous integration environment.\"&gt;\r\n&lt;exec executable=\"${phpmd}\" taskname=\"phpmd\"&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;arg value=\"xml\" \/&gt;\r\n&lt;arg path=\"${basedir}\/build\/phpmd.xml\" \/&gt;\r\n&lt;arg value=\"--reportfile\" \/&gt;\r\n&lt;arg path=\"${basedir}\/build\/logs\/pmd.xml\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpmd.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpcs\"\r\nunless=\"phpcs.done\"\r\ndescription=\"Find coding standard violations using PHP_CodeSniffer and print human readable output. Intended for usage on the command line before committing.\"&gt;\r\n&lt;exec executable=\"${phpcs}\" taskname=\"phpcs\"&gt;\r\n&lt;arg value=\"--standard=PSR2\" \/&gt;\r\n&lt;arg value=\"--extensions=php\" \/&gt;\r\n&lt;arg value=\"--ignore=autoload.php\" \/&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;arg path=\"${basedir}\/tests\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpcs.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpcs-ci\"\r\nunless=\"phpcs.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Find coding standard violations using PHP_CodeSniffer and log result in XML format. Intended for usage within a continuous integration environment.\"&gt;\r\n&lt;exec executable=\"${phpcs}\" output=\"\/dev\/null\" taskname=\"phpcs\"&gt;\r\n&lt;arg value=\"--report=checkstyle\" \/&gt;\r\n&lt;arg value=\"--report-file=${basedir}\/build\/logs\/checkstyle.xml\" \/&gt;\r\n&lt;arg value=\"--standard=PSR2\" \/&gt;\r\n&lt;arg value=\"--extensions=php\" \/&gt;\r\n&lt;arg value=\"--ignore=autoload.php\" \/&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;arg path=\"${basedir}\/tests\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpcs.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpcpd\"\r\nunless=\"phpcpd.done\"\r\ndescription=\"Find duplicate code using PHPCPD and print human readable output. Intended for usage on the command line before committing.\"&gt;\r\n&lt;exec executable=\"${phpcpd}\" taskname=\"phpcpd\"&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpcpd.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpcpd-ci\"\r\nunless=\"phpcpd.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Find duplicate code using PHPCPD and log result in XML format. Intended for usage within a continuous integration environment.\"&gt;\r\n&lt;exec executable=\"${phpcpd}\" taskname=\"phpcpd\"&gt;\r\n&lt;arg value=\"--log-pmd\" \/&gt;\r\n&lt;arg path=\"${basedir}\/build\/logs\/pmd-cpd.xml\" \/&gt;\r\n&lt;arg path=\"${basedir}\/src\" \/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpcpd.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpunit\"\r\nunless=\"phpunit.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Run unit tests with PHPUnit\"&gt;\r\n&lt;exec executable=\"${phpunit}\" resultproperty=\"result.phpunit\" taskname=\"phpunit\"&gt;\r\n&lt;arg value=\"--configuration\"\/&gt;\r\n&lt;arg path=\"${basedir}\/build\/phpunit.xml\"\/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpunit.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpunit-no-coverage\"\r\nunless=\"phpunit.done\"\r\ndepends=\"prepare\"\r\ndescription=\"Run unit tests with PHPUnit (without generating code coverage reports)\"&gt;\r\n&lt;exec executable=\"${phpunit}\" failonerror=\"true\" taskname=\"phpunit\"&gt;\r\n&lt;arg value=\"--configuration\"\/&gt;\r\n&lt;arg path=\"${basedir}\/build\/phpunit.xml\"\/&gt;\r\n&lt;arg value=\"--no-coverage\"\/&gt;\r\n&lt;\/exec&gt;\r\n\r\n&lt;property name=\"phpunit.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"phpdox\"\r\nunless=\"phpdox.done\"\r\ndepends=\"phploc-ci,phpcs-ci,phpmd-ci\"\r\ndescription=\"Generate project documentation using phpDox\"&gt;\r\n&lt;exec executable=\"${phpdox}\" dir=\"${basedir}\/build\" taskname=\"phpdox\"\/&gt;\r\n\r\n&lt;property name=\"phpdox.done\" value=\"true\"\/&gt;\r\n&lt;\/target&gt;\r\n\r\n&lt;target name=\"-check-failure\"&gt;\r\n&lt;fail message=\"PHPUnit did not finish successfully\"&gt;\r\n&lt;condition&gt;\r\n&lt;not&gt;\r\n&lt;equals arg1=\"${result.phpunit}\" arg2=\"0\"\/&gt;\r\n&lt;\/not&gt;\r\n&lt;\/condition&gt;\r\n&lt;\/fail&gt;\r\n&lt;\/target&gt;\r\n&lt;\/project&gt;<\/pre>\n<p>&nbsp;<\/p>\n<ul>\n<li>full-build &#8211; to domy\u015blny target. Uruchamia on wszystkie narz\u0119dzia w taki spos\u00f3b, \u017ce logi XML pisane s\u0105 do domy\u015blnych lokalizacji. Full-build powinien by\u0107 przeprowadzany w nocy ze wzgl\u0119du na d\u0142ugi czas wykonywania.<\/li>\n<li>full-build-paralel &#8211; robi to samo co full-build z t\u0105 r\u00f3\u017cnic\u0105, \u017ce statyczne narz\u0119dzia analizy uruchamiane s\u0105 r\u00f3wnolegle. Nawet na maszynie z wieloma procesorami pe\u0142ny build mo\u017ce trwa\u0107 du\u017co czasu dlatego ten target powinien by\u0107 uruchamiany r\u00f3wnie\u017c w nocy.<\/li>\n<li>quick-build &#8211; target uruchamiany przez &#8220;d\u017coby&#8221; wyzwalane w czasie wgrywania nowego kodu do repozytorium.<\/li>\n<li>clean &#8211; u\u017cywany do kasowania artefakt\u00f3w (np. log\u00f3w i innych rzeczy generowanych w czasie buildu).<\/li>\n<li>lint &#8211; u\u017cywany do testowania sk\u0142adni kodu projektu (php -l). To zadanie mo\u017ce by\u0107 u\u017cywane przed commitem.<\/li>\n<li>phpcs &#8211; u\u017cywany do odnajdywania narusze\u0144 standardu kodowania. Wy\u015bwietla wyniki czytelne dla cz\u0142owieka. To zadanie mo\u017ce by\u0107 u\u017cywane przed commitem.<\/li>\n<li>phpcpd &#8211; u\u017cywany do odnajdywania zduplikowanego kodu. Wy\u015bwietla wyniki czytelne dla cz\u0142owieka. To zadanie mo\u017ce by\u0107 u\u017cywane przed commitem.<\/li>\n<li>phpmd &#8211; u\u017cywany do odnajdywania ba\u0142aganu w projekcie. Wy\u015bwietla wyniki czytelne dla cz\u0142owieka. To zadanie mo\u017ce by\u0107 u\u017cywane przed commitem.<\/li>\n<li>phpunit &#8211; u\u017cywany do uruchamiania test\u00f3w jednostkowych. To zadanie mo\u017ce by\u0107 u\u017cywane przed commitem.<\/li>\n<li>phpdox &#8211; u\u017cywany do generowania dokumentacji projektu.<\/li>\n<li>phploc &#8211; u\u017cywany do obliczania rozmiaru projektu.<\/li>\n<\/ul>\n<p>Uruchomienie build.xml spowoduje wygenerowanie katalogu o poni\u017cszej zawarto\u015bci:<\/p>\n<pre class=\"lang:sh decode:true\">build\r\n|-- api ...\r\n|-- coverage ...\r\n`-- logs\r\n|-- checkstyle.xml\r\n|-- clover.xml\r\n|-- crap4j.xml\r\n|-- jdepend.xml\r\n|-- junit.xml\r\n|-- phploc.csv\r\n|-- pmd-cpd.xml\r\n`-- pmd.xml<\/pre>\n<p>Artefakty te b\u0119d\u0105 nast\u0119pnie przetwarzane przez Jenkinsa.<\/p>\n<p>Ze strony http:\/\/jenkins-php.org pobieramy szablon nowego &#8220;job&#8221; Jenkinsa. Katalog domowy Jenkinsa ($<code>JENKINS_HOME<\/code>) to w systemach RedHat-opodobnych <code>\/var\/lib\/jenkins<\/code>:<\/p>\n<pre class=\"lang:sh decode:true\">cd $JENKINS_HOME\/jobs\r\nmkdir php-template\r\ncd php-template\r\nwget https:\/\/raw.github.com\/sebastianbergmann\/php-jenkins-template\/master\/config.xml\r\ncd ..\r\nchown -R jenkins:jenkins php-template\/<\/pre>\n<p>Prze\u0142adowujemy konfiguracj\u0119 Jenkinsa:<\/p>\n<pre class=\"lang:sh decode:true\">java -jar jenkins-cli.jar -s http:\/\/localhost:8080 reload-configuration<\/pre>\n<p>W przypadku b\u0142\u0119d\u00f3w przy pr\u00f3bie prze\u0142adowania mo\u017cna zrestartowa\u0107 serwer Jenkinsa. Nast\u0119pnie w Jenkinsie:<\/p>\n<ol>\n<li>Klikamy &#8220;New Item&#8221;.<\/li>\n<li>Wpisujemy nazw\u0119 w polu\u00a0 &#8220;Enter an item name&#8221;.<\/li>\n<li>W polu &#8220;Copy from&#8221;\u00a0 wpisujemy &#8220;php-template&#8221;.<\/li>\n<li>Klikamy &#8220;OK&#8221;.<\/li>\n<li>Odznaczamy (odhaczamy) opcj\u0119 &#8220;Disable Build&#8221;.<\/li>\n<li>Wpisujemy URL do projektu PHP na GIT w &#8220;Source Code Management&#8221;.<\/li>\n<li>Konfigurujemy &#8220;Build Trigger&#8221; na &#8220;Poll SCM&#8221;.<\/li>\n<li>Klikamy &#8220;Save&#8221;.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>W tym artykule poszerzymy plik Anta build.xml o testy jednostkowe przeprowadzane przy pomocy PHPUnit.<\/p>\n","protected":false},"author":1,"featured_media":2116,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[54],"tags":[],"_links":{"self":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/2095"}],"collection":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/comments?post=2095"}],"version-history":[{"count":16,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/2095\/revisions"}],"predecessor-version":[{"id":2120,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/2095\/revisions\/2120"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media\/2116"}],"wp:attachment":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media?parent=2095"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/categories?post=2095"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/tags?post=2095"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}