Continous delivery pipeline
for Symfony2 projects with
Jenkins and Chef
Michał Dąbrowski
http://github.com/defrag
PHPers Kraków 10/07/2014
Most common anwser?
Most common anwser?
Should be done
Most common anwser?
Should be done
„Continuous delivery (CD) is a set of
processes, tools and techniques for the
rapid, reliable and continuous
development and delivery of software.”
What is continous
delivery?
Our highest priority is to satisfy the
customer!
through early and continuous delivery!
of valuable software.
Agile manifesto #1
done === released
What is done in
Continous Delivery?
Why?
increase quality
reduce cost
reduct risk
make customer happy
delivery production ready software
act on feedback
Quality comes first
Building blocks from
practical view
Continous Integration
Release automation
Infrastructure automation
Monitoring
CI & Deployment
pipeline
Typical development
workflow
Fork a repo
Typical development
workflow
Submit pull request
Typical development
workflow
Trigger build process on PR
Typical development
workflow
Code review
Typical development
workflow
Merge into master
Typical development
workflow
Trigger build on master branch
Typical development
workflow
Result of build is Release Candidate!
(not every RC is deployed)
How do we get
there?
Start with Jenkins
Create new project
Set up your build
process
Set up your build
process
<target name="configure">
<echo>Downloading dependencies using composer.</echo>
<exec executable="/bin/bash" failonerror="true" dir=„.">
<arg value="/usr/bin/composer install —no-interaction —prefer-dist" />!
</exec>
!
<echo>Dumping prod assets.</echo>
<exec executable="/bin/bash" failonerror="true">
<arg value="-c" />
<arg value="${basedir}/bin/console assetic:dump --env=prod --no-debug" />!
</exec>
!
<echo>Ensuring empty cache and logs directories.</echo>
<delete includeemptydirs="true" verbose="false" failonerror="true" dir="${basedir}/var/cache" />!
<delete includeemptydirs="true" verbose="false" failonerror="true" dir="${basedir}/var/logs" />!
<mkdir dir="${basedir}/var/cache" />!
<mkdir dir="${basedir}/var/logs" />
</target>
Run your unit tests
Run your unit tests
<target name=„phpspec" description="Run tests with PHPSpec">
<exec executable="/bin/bash" failonerror="true">
<arg value="-c" />
<arg value="${basedir}/bin/phpspec run" />
</exec>
</target>
<target name="build-unit">
<property file="build.ci.properties" />
<antcall target="phpspec" /> !
<antcall target="jasmine" />
<echo>Unit test build pass.</echo>
</target>
Run your acceptance
tests
Run your acceptance
tests
<target name=„behat" description=„Run acceptance tests with Behat">
<exec executable="/bin/bash" failonerror="true">
<arg value="-c" />
<arg value="${basedir}/bin/behat —format progress" />!
</exec>
</target>
<target name="build-acceptance">
<property file="build.ci.properties" />
<antcall target="behat" /> !
<echo>Acceptance test build pass.</echo>
</target>
Create package out
of build result
• tarball!
• rpm!
• deb!
• etc.
Create package out
of build result
Visualize your process
with build pipeline
Stop
Deploy time
Not only application
Deliver your configuration in automated fashion
Build pipeline
revisited
manualauto
Quick Chef overview
Make jenkins talk to
your chef server
knife ec2 server create!
knife bootstrap!
knife ssh!
…
Make jenkins talk to
your chef server
Deploy app
capistrano, fabric, knife plugin etc
Chose the one that
works for you
Dead simple with
Fabric and pychef
@roles('web')!
def deploy():
…
Dead simple with
Fabric and pychef
fab env:staging deploy:25
Dead simple with
Fabric and pychef
fab env:staging deploy:25
chef environment build no.
Demo
Wrapping up
Benefits
speed of delivery
quality
cost reduction
ability to respond to feedback quickly
adapt to change
Thank you

Continous delivery with Jenkins and Chef