Jenkins for
PHP projects

Stephan Hochdörfer // June 23 2015

About me


  • Stephan Hochdörfer
  • Head of Technology, bitExpert AG
    (Mannheim, Germany)
  • S.Hochdoerfer@bitExpert.de
  • @shochdoerfer

  • #PHP, #DevOps, #Automation, #unKonf

Our story: Diversity

Jenkins Use Cases


  • Running continuous build

  • Running nightly builds

  • Running integration tests

  • Running Satis builds

General Jenkins set-up

Jenkins Project Overview

Icon Config Management

Jenkins Job Icon Config

Config File Management

Jenkins Node Overview

Jenkins Node Config

Jenkins Node Environment

Continuous build




« [...] environments automatically rebuild the project whenever
changes are checked in - often several times a day -
and provide more immediate feedback » - Wikipedia

Our typical (PHP) toolchain




Composer, Phing, PHPUnit,

PHP_CodeSniffer, PDepend, PHPCPD

Project structure

/tmp/myproject
   |-build
   |---coverage
   |---logs
   |---pdepend
   |-docs
   |-src
   |---Vendor
   |-----MyProject
   |-tests
   |---Vendor
   |-----MyProject
   |-vendor
   |-web
   |-build.xml
   |-composer.json
   |-composer.lock
   |-phpdoc.dist.xml
   |-phpmd.xml
   |-phpunit.xml.dist

Phing build.xml

<?xml version="1.0"?>
<project name="ci" default="ci:help" basedir=".">

    <target name="-ci:clean"
            depends="-init"
            hidden="true">

        <delete dir="${phing.dir}/build/logs" quiet="true" />
    </target>

    <target name="-ci:prepare"
            depends="-init, -ci:clean"
            hidden="true" >

        <mkdir dir="${phing.dir}/build/logs"/>
    </target>

    <target name="ci:build"
            depends="-init, -ci:prepare, ci:pdepend, ci:phpunit, 
            ci:phpcpd, ci:phpmd, ci:phpcs" />
</project>

Jenkins Job Config

Label Usage

Environment configuration

Push config files to node

Validate composer.json

Installing dependencies

Running Phing

Installing npm dependencies

Running Grunt

Process the build results

Email notifications

Email notifications

Trigger HHVM / PHP7 builds

Execute HHVM build

Trigger Satis build

Running nightly builds




« A nightly build is a neutral build that takes place automatically. These typically take place when no one is likely to be working in the office [...] » - Wikipedia

Security issues?




Check composer.lock file


$ php security-checker.phar security:check ./composer.lock
Security Check Report
~~~~~~~~~~~~~~~~~~~~~

Checked file: composer.lock


  [OK]
  0 packages have known vulnerabilities

Security Checker Phing task

Automate with Jenkins

Running integration tests




« [...] is the phase in software testing in which individual software modules are combined and tested as a group. » - Wikipedia

Running Phing

Running Grunt

Running Satis builds




Satis is a ultra-lightweight, static
file-based version of packagist.

Installing Satis

$ composer.phar create-project composer/satis --stability=dev
{
    "name": "bitExpert Satis repo",
    "homepage": "https://satis.loc",
    "repositories": [
        { "type": "vcs", "url": "/srv/repos/project-1.git" },
        { "type": "vcs", "url": "/srv/repos/project-2.git" }
    ],
    "require-all": true,
    "archive": {
        "directory": "dist",
        "format": "zip",
        "skip-dev": false
    }
}

Running Satis

$ php bin/satis build config.json web/
$ php bin/satis build config.json web/ customername/project1

Jenkins Satis Job Config

Define Job Param (Package)

Define Job Param (Recipient)

Running Satis build

Rewrite repo urls

Cleanup old files

Notify users after build

Running the build

Console output

Satis repository

Run Composer

$ composer.phar require customername/project1
Using version ^1.0 for customername/project1
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing customername/project1 (1.0.0)
    Downloading: 100%

Writing lock file
Generating autoload files

Jenkins Plugins Reference








Thank you! Questions?