Building and Deploying PHP Apps Using phing
-
Upload
mihail-irintchev -
Category
Software
-
view
524 -
download
3
description
Transcript of Building and Deploying PHP Apps Using phing
HOW TO DEPLOY PHP APPLICATIONSSAFELY, EFFICIENTLY, AND FREQUENTLY
WITHOUT LOOSING YOUR SANITY (COMPLETELY)Created by Mihail Irintchev
Head of Software Development
SiteGround.com Web Hosting Co.
/ [email protected] @irintchev
ABOUT MEName: Mihail Irintchev (Mike)From Sofia, BulgariaWeb developer since 2003Work @ SiteGroundOrganizing @bgphp UGLove beer
MY USUAL ACTIVITIES
MY CAR
MY OFFICE
WHAT IS YOUR DEPLOYMENT PROCESS LIKE?
OVERVIEW OF BUILD ESSENTIALS:Revision control systemContinuous testingContinuous integrationStaging environmentAutomatic documentationCode health metricsDeployment mechanism
... and you want all that plus more wrapped in ...
AN AUTOMATED BUILD PROCEDURE!
REVISION CONTROL SYSTEMS
SOME LESS COMMON ONES
BASIC DISTINCTION BETWEENVERSIONING SYSTEMS
Local data model Distributed model
SVN GIT
CVS Bazaar
darcs
BASIC DISTINCTION BETWEEN MODELS
WHAT CAN THE VERSION CONTROLDO FOR YOU?
(APART FROM STORING AND VERSIONING YOUR CODE)
pre-commit and post-commit hooks
WHAT IS PRE-COMMIT GOOD FOR?PREVENT PEOPLE FROM COMMITTING BAD CODE
Run php lint (php -l) on the newly committed code
for i in $SVNLOOK changed -t "$TXN" "$REPOS" | $AWK '{print $2}'do if [[ $i =~ "\.php$" ]]; then # Run php lint to make sure no code with parse errors is committed CHECK=$SVNLOOK cat -t "$TXN" "$REPOS" $i | $PHP -d html_errors=off -l || echo $i RETURN=echo $CHECK | $GREP "No syntax" > /dev/null && echo TRUE || echo FALSE if [ $RETURN = 'FALSE' ]; then echo $CHECK 1>&2; exit 1 fi fidone
ENFORCE CODE STANDARDSRun PHP_CodeSniffer (phpcs)Catch any serious violations (use levels)
<?phpecho "Hello world!";
#phpcs hello.php
FILE: /home/madasha/tmp/hello.php--------------------------------------------------------------------------------FOUND 1 ERROR(S) AFFECTING 1 LINE(S)-------------------------------------------------------------------------------- 2 | ERROR | Missing file doc comment--------------------------------------------------------------------------------
Time: 16 ms, Memory: 2.50Mb
PREVENT SOME FOOLISH MISTAKES... like dumping DB user and pass on your home page... or embarass yourself by leaving some othervar_dump() / print_r() / var_export() behind
THE "GOLDEN" RULE
SO JUST ADD ANOTHER SECTION TO THE PRE-COMMIT HOOKif [[ $i =~ "\.php$" ]]; then # ...
# Grep for var_dump/var_export/print_r (the last two without second param passed) # to prevent code committed with debugging instructions to go into the repo CHECK=$SVNLOOK cat -t "$TXN" "$REPOS" $i | \ $GREP -e "\(var_dump[ \t]*(\|\(var_export\|print_r\)[ \t]*([,)]\+)\)" -m1 -c RETURN=echo $CHECK | $GREP "1" > /dev/null && echo TRUE || echo FALSE if [ $RETURN = 'TRUE' ]; then echo "var_dump/print_r/var_export found in $i" 1>&2; exit 2 fi
# ... fi
ANYTHING ELSE?YOUR IMAGINATION IS PRETTY MUCH THE BOUNDARY
WHAT IS POST-COMMIT GOOD FOR?Automated loggingNotifications
THERE ARE OTHER HOOKS AS WELLSVN GIT
pre-lockpre-unlockpost-lockpost-unlockstart-commitpre-revprop-changepost-revprop-change
prepare-commit-msgpost-mergepre-receivepost-receivepost-checkoutpre-applypatchpost-applypatch
THE BUILD SOFTWARE
WHAT DOES PHING STAND FOR?PHing Is Not GNU make
“It's a PHP project build system or build toolbased on . You can do anythingwith it that you could do with a traditional
build system like GNU make...”
Apache Ant
BUT WHY PHING?
SERIOUSLY, WHY PHING?Very flexible and robust build toolSimple XML build fileVariety of built-in and optional tasksVery easy to write your own custom taskGood and communityPlatform independentNo required external dependencies
docs
VERY EASY INSTALLATIONThrough PEAR:
$ pear channel-discover pear.phing.info$ pear install [--alldeps] phing/phing
Through Composer:
{ "require-dev": { "phing/phing": "2.*" }}
A SAMPLE XML BUILD FILE
<?xml version="1.0" encoding="UTF-8"?><project name="FooBar" default="dist"> <!-- ============================================ --> <!-- Target: prepare --> <!-- ============================================ --> <target name="prepare"> <echo msg="Making directory ./build" /> <mkdir dir="./build" /> </target> <!-- ============================================ --> <!-- Target: build --> <!-- ============================================ --> <target name="build" depends="prepare"> <echo msg="Copying files to build directory..." /> <echo msg="Copying ./about.php to ./build directory..." /> <copy file="./about.php" tofile="./build/about.php" /> <echo msg="Copying ./browsers.php to ./build directory..." /> <copy file="./browsers.php" tofile="./build/browsers.php" /> <echo msg="Copying ./contact.php to ./build directory..." /> <copy file="./contact.php" tofile="./build/contact.php" /> </target> <!-- ============================================ --> <!-- (DEFAULT) Target: dist -->
TASK #1: UPDATE FROM SVN
<!-- ============================================================ --><!-- Target: svn_update - updates from svn, prints last revision --><!-- ============================================================ --><target name="svn_update"> <svnupdate svnpath="/usr/bin/svn" nocache="true" username="${svn_user}" password="${svn_pass}" todir="${srcdir}" />
<svnlastrevision svnpath="/usr/bin/svn" workingcopy="${srcdir}" propertyname="svn.lastrevision" /> <echo msg="Updated ${srcdir} to revision ${svn.lastrevision}" /></target>
TASK #2: UNIT-TESTSWHAT IS YOUR PHP UNIT-TESTING PREFERRED FRAMEWORK?
By Sebastian Bergmann
TASK #2: RUN UNIT-TESTS IN PHING
<!-- ===================================================================== --><!-- Target: phpunit - a subtask that runs PHPUnit on phpunit tests/suits --><!-- ===================================================================== --><target name="phpunit"> <echo msg="Running PHPUnit tests after SVN update:" /> <phpunit haltonfailure="true" haltonerror="true" bootstrap="bootstrap.php"> <formatter type="plain" usefile="false" /> <batchtest> <fileset dir="tests"> <include name="*Test.php"/> </fileset> </batchtest> </phpunit></target>
TASK #3: JS UNIT-TESTSYour client-side code can be just as crucial as the server-side
one, so why not test it continuously as well?
THE TOOLS?
TASK #3: RUN QUNIT TESTS IN PHING
<path id="project.class.path"> <pathelement dir="./lib/" /></path>
<taskdef name="qunit" classname="QunitTask"> <classpath refid="project.class.path" /></taskdef>
<target name="qunit" description="JavaScript Unit Test"> <qunit executable="/usr/bin/phantomjs" haltonfailure="true" runner="lib/run-qunit.js"> <fileset dir="."> <include name="jstests/runner.htm" /> </fileset> </qunit></target>
The example above is using by MartinJonsson
Qunit Phing Task
TASK #4: AUTOMATIC DOCUMENTATIONThe tool: phpDocumentor 2
<phpdoc2 title="Gallery Documentation" destdir="docs" template="responsive-twig"> <fileset dir="./classes"> <include name="**/*.php" /> </fileset></phpdoc2>
CODE METRICS TASKSTHE TOOLS?
phpmdphpcpdpdependphpcs
Guess what? There exist ready-made phing tasks for all ofthem!
TASKS #5: PHPMDPerson behind: Manuel Pichler
<!-- ===================================================================== --><!-- Target: phpmd - a subtask that runs PHPMD on predefined dirs/files --><!-- and generates reports in the desired format --><!-- ===================================================================== --><target name="phpmd"> <phpmd rulesets="cleancode,design,unusedcode"> <fileset dir="${srcdir}"> <include name="classes/**/*.php" /> </fileset> <formatter type="xml" outfile="${srcdir}/reports/pmd.xml"/> </phpmd></target>
TASK #6: PHPCPDPerson behind: Sebastian Bergmann
<!-- ===================================================================== --><!-- Target: phpcpd - a subtask that runs PHPCPD on predefined dirs/files --><!-- and generates reports in the desired format --><!-- ===================================================================== --><target name="phpcpd"> <phpcpd> <fileset dir="${srcdir}"> <include name="classes/**/*.php" /> </fileset> <formatter type="pmd" outfile="${srcdir}/reports/pmd-cpd.xml"/> </phpcpd></target>
TASK #7: PDEPENDPerson behind: Manuel Pichler
<!-- ===================================================================== --><!-- Target: pdepend - a subtask that runs pdepend on predefined dirs/files--><!-- and generates reports in the desired format --><!-- ===================================================================== --><target name="pdepend"> <phpdepend> <fileset dir="${srcdir}"> <include name="classes/**/*.php" /> </fileset>
<logger type="jdepend-xml" outfile="${srcdir}/reports/pdepend.xml"/> <logger type="jdepend-chart" outfile="${srcdir}/reports/pchart.svg"/> <logger type="overview-pyramid" outfile="${srcdir}/reports/pyramid.svg"/> <analyzer type="coderank-mode" value="method"/> </phpdepend></target>
WHAT ELSE CAN YOU USE PHING FOR?Encrypting/obfuscating code before deploymentGenerating static assetsGenerate and deploy static sites with tools like sculpinExecute post-deploy scriptsPretty much anything useful around the build/deploy
TAKEAWAYSThere are a lot of things you can automate in a build(strong emphasis on continuous testing & integration)
There are a lot of tools out there that can help you do that
phing is a very neat tool to organize your build process
CREDITS & REFERENCES"Quality Assurance for PHP Projects" by Michelangelo van Dam
by Jordan Kasper"Browser Eyeballing != JavaScript Testing"
The PHP Quality Assurance Toolchain
QUESTIONS?