SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
HOW TO DEPLOY PHP APPLICATIONS
SAFELY, EFFICIENTLY, AND FREQUENTLY
WITHOUT LOOSING YOUR SANITY (COMPLETELY)
Created by Mihail Irintchev
Head of Software Development
SiteGround.com Web Hosting Co.
/m.irintchev@siteground.com @irintchev
ABOUT ME
Name: Mihail Irintchev (Mike)
From Sofia, Bulgaria
Web developer since 2003
Work @ SiteGround
Organizing @bgphp UG
Love beer
MY USUAL ACTIVITIES
MY CAR
MY OFFICE
WHAT IS YOUR DEPLOYMENT PROCESS LIKE?
OVERVIEW OF BUILD ESSENTIALS:
Revision control system
Continuous testing
Continuous integration
Staging environment
Automatic documentation
Code health metrics
Deployment mechanism
... and you want all that plus more wrapped in ...
AN AUTOMATED BUILD PROCEDURE!
REVISION CONTROL SYSTEMS
C'MON, IT'S 2014 !!!
SOME LESS COMMON ONES
BASIC DISTINCTION BETWEEN
VERSIONING SYSTEMS
Local data model Distributed model
SVN GIT
CVS Bazaar
darcs
BASIC DISTINCTION BETWEEN MODELS
WHAT CAN THE VERSION CONTROL
DO 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
fi
done
ENFORCE CODE STANDARDS
Run PHP_CodeSniffer (phpcs)
Catch any serious violations (use levels)
<?php
echo "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 other
var_dump()/ print_r()/ var_export()behind
THE "GOLDEN" RULE
SO JUST ADD ANOTHER SECTION TO THE PRE-COMMIT HOOK
if [[ $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 logging
Notifications
THERE ARE OTHER HOOKS AS WELL
SVN GIT
pre-lock
pre-unlock
post-lock
post-unlock
start-commit
pre-revprop-change
post-revprop-change
prepare-commit-msg
post-merge
pre-receive
post-receive
post-checkout
pre-applypatch
post-applypatch
THE BUILD SOFTWARE
WHAT DOES PHING STAND FOR?
PHing Is Not GNU make
“It's a PHP project build system or build tool
based on . You can do anything
with 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 tool
Simple XML build file
Variety of built-in and optional tasks
Very easy to write your own custom task
Good and community
Platform independent
No required external dependencies
docs
VERY EASY INSTALLATION
Through 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-TESTS
WHAT 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-TESTS
Your 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 Martin
Jonsson
Qunit Phing Task
TASK #4: AUTOMATIC DOCUMENTATION
The tool: phpDocumentor 2
<phpdoc2 title="Gallery Documentation"
destdir="docs"
template="responsive-twig">
<fileset dir="./classes">
<include name="**/*.php" />
</fileset>
</phpdoc2>
CODE METRICS TASKS
THE TOOLS?
phpmd
phpcpd
pdepend
phpcs
Guess what? There exist ready-made phing tasks for all of
them!
TASKS #5: PHPMD
Person 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: PHPCPD
Person 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: PDEPEND
Person 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 PHINGFOR?
Encrypting/obfuscating code before deployment
Generating static assets
Generate and deploy static sites with tools like sculpin
Execute post-deploy scripts
Pretty much anything useful around the build/deploy
TAKEAWAYS
There 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?
THANK YOU!
m.irintchev@siteground.com
@irintchev

Weitere ähnliche Inhalte

Was ist angesagt?

Putting Phing to Work for You
Putting Phing to Work for YouPutting Phing to Work for You
Putting Phing to Work for Youhozn
 
Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Michiel Rook
 
Best Practices in PHP Application Deployment
Best Practices in PHP Application DeploymentBest Practices in PHP Application Deployment
Best Practices in PHP Application DeploymentShahar Evron
 
Practical PHP Deployment with Jenkins
Practical PHP Deployment with JenkinsPractical PHP Deployment with Jenkins
Practical PHP Deployment with JenkinsAdam Culp
 
Propel Your PHP Applications
Propel Your PHP ApplicationsPropel Your PHP Applications
Propel Your PHP Applicationshozn
 
PHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBeneluxPHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBeneluxNick Belhomme
 
Zend Framework 1.8 workshop
Zend Framework 1.8 workshopZend Framework 1.8 workshop
Zend Framework 1.8 workshopNick Belhomme
 
Php Dependency Management with Composer ZendCon 2016
Php Dependency Management with Composer ZendCon 2016Php Dependency Management with Composer ZendCon 2016
Php Dependency Management with Composer ZendCon 2016Clark Everetts
 
Zend con 2016 bdd with behat for beginners
Zend con 2016   bdd with behat for beginnersZend con 2016   bdd with behat for beginners
Zend con 2016 bdd with behat for beginnersAdam Englander
 
Virtual Bolt Workshop - Dell - April 8 2020
Virtual Bolt Workshop - Dell - April 8 2020Virtual Bolt Workshop - Dell - April 8 2020
Virtual Bolt Workshop - Dell - April 8 2020Puppet
 
11 tools for your PHP devops stack
11 tools for your PHP devops stack11 tools for your PHP devops stack
11 tools for your PHP devops stackKris Buytaert
 
Vagrant move over, here is Docker
Vagrant move over, here is DockerVagrant move over, here is Docker
Vagrant move over, here is DockerNick Belhomme
 
Virtual Bolt Workshop - 6 May
Virtual Bolt Workshop - 6 MayVirtual Bolt Workshop - 6 May
Virtual Bolt Workshop - 6 MayPuppet
 
Ansible project-deploy (NomadPHP lightning talk)
Ansible project-deploy (NomadPHP lightning talk)Ansible project-deploy (NomadPHP lightning talk)
Ansible project-deploy (NomadPHP lightning talk)Ramon de la Fuente
 
Modulesync- How vox pupuli manages 133 modules, Tim Meusel
Modulesync- How vox pupuli manages 133 modules, Tim MeuselModulesync- How vox pupuli manages 133 modules, Tim Meusel
Modulesync- How vox pupuli manages 133 modules, Tim MeuselPuppet
 
New EEA Plone Add-ons
New EEA Plone Add-onsNew EEA Plone Add-ons
New EEA Plone Add-onsAlin Voinea
 
Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...
Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...
Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...Puppet
 
Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)
Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)
Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)Puppet
 
Laravel 4 package development
Laravel 4 package developmentLaravel 4 package development
Laravel 4 package developmentTihomir Opačić
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend frameworkAlan Seiden
 

Was ist angesagt? (20)

Putting Phing to Work for You
Putting Phing to Work for YouPutting Phing to Work for You
Putting Phing to Work for You
 
Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)
 
Best Practices in PHP Application Deployment
Best Practices in PHP Application DeploymentBest Practices in PHP Application Deployment
Best Practices in PHP Application Deployment
 
Practical PHP Deployment with Jenkins
Practical PHP Deployment with JenkinsPractical PHP Deployment with Jenkins
Practical PHP Deployment with Jenkins
 
Propel Your PHP Applications
Propel Your PHP ApplicationsPropel Your PHP Applications
Propel Your PHP Applications
 
PHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBeneluxPHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBenelux
 
Zend Framework 1.8 workshop
Zend Framework 1.8 workshopZend Framework 1.8 workshop
Zend Framework 1.8 workshop
 
Php Dependency Management with Composer ZendCon 2016
Php Dependency Management with Composer ZendCon 2016Php Dependency Management with Composer ZendCon 2016
Php Dependency Management with Composer ZendCon 2016
 
Zend con 2016 bdd with behat for beginners
Zend con 2016   bdd with behat for beginnersZend con 2016   bdd with behat for beginners
Zend con 2016 bdd with behat for beginners
 
Virtual Bolt Workshop - Dell - April 8 2020
Virtual Bolt Workshop - Dell - April 8 2020Virtual Bolt Workshop - Dell - April 8 2020
Virtual Bolt Workshop - Dell - April 8 2020
 
11 tools for your PHP devops stack
11 tools for your PHP devops stack11 tools for your PHP devops stack
11 tools for your PHP devops stack
 
Vagrant move over, here is Docker
Vagrant move over, here is DockerVagrant move over, here is Docker
Vagrant move over, here is Docker
 
Virtual Bolt Workshop - 6 May
Virtual Bolt Workshop - 6 MayVirtual Bolt Workshop - 6 May
Virtual Bolt Workshop - 6 May
 
Ansible project-deploy (NomadPHP lightning talk)
Ansible project-deploy (NomadPHP lightning talk)Ansible project-deploy (NomadPHP lightning talk)
Ansible project-deploy (NomadPHP lightning talk)
 
Modulesync- How vox pupuli manages 133 modules, Tim Meusel
Modulesync- How vox pupuli manages 133 modules, Tim MeuselModulesync- How vox pupuli manages 133 modules, Tim Meusel
Modulesync- How vox pupuli manages 133 modules, Tim Meusel
 
New EEA Plone Add-ons
New EEA Plone Add-onsNew EEA Plone Add-ons
New EEA Plone Add-ons
 
Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...
Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...
Easily Manage Patching and Application Updates with Chocolatey + Puppet - Apr...
 
Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)
Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)
Puppet Virtual Bolt Workshop - 23 April 2020 (Singapore)
 
Laravel 4 package development
Laravel 4 package developmentLaravel 4 package development
Laravel 4 package development
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend framework
 

Andere mochten auch

Desplegando código con Phing, PHPunit, Coder y Jenkins
Desplegando código con Phing, PHPunit, Coder y JenkinsDesplegando código con Phing, PHPunit, Coder y Jenkins
Desplegando código con Phing, PHPunit, Coder y JenkinsLa Drupalera
 
Introduction à l'intégration continue en PHP
Introduction à l'intégration continue en PHPIntroduction à l'intégration continue en PHP
Introduction à l'intégration continue en PHPEric Hogue
 
Continuous Integration and Deployment Patterns for Magento
Continuous Integration and Deployment Patterns for MagentoContinuous Integration and Deployment Patterns for Magento
Continuous Integration and Deployment Patterns for MagentoAOE
 
Ain't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to AutomationAin't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to Automationmfrost503
 
Build & deploy PHP application (intro level)
Build & deploy PHP application (intro level)Build & deploy PHP application (intro level)
Build & deploy PHP application (intro level)Anton Babenko
 
PHP Cloud Deployment Toolkits
PHP Cloud Deployment ToolkitsPHP Cloud Deployment Toolkits
PHP Cloud Deployment ToolkitsMitch Pirtle
 
Symfony under control. Continuous Integration and Automated Deployments in Sy...
Symfony under control. Continuous Integration and Automated Deployments in Sy...Symfony under control. Continuous Integration and Automated Deployments in Sy...
Symfony under control. Continuous Integration and Automated Deployments in Sy...Max Romanovsky
 
Rock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment WorkflowsRock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment WorkflowsAOE
 

Andere mochten auch (9)

Desplegando código con Phing, PHPunit, Coder y Jenkins
Desplegando código con Phing, PHPunit, Coder y JenkinsDesplegando código con Phing, PHPunit, Coder y Jenkins
Desplegando código con Phing, PHPunit, Coder y Jenkins
 
Introduction à l'intégration continue en PHP
Introduction à l'intégration continue en PHPIntroduction à l'intégration continue en PHP
Introduction à l'intégration continue en PHP
 
Continuous Integration and Deployment Patterns for Magento
Continuous Integration and Deployment Patterns for MagentoContinuous Integration and Deployment Patterns for Magento
Continuous Integration and Deployment Patterns for Magento
 
Ain't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to AutomationAin't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to Automation
 
Juc boston2014.pptx
Juc boston2014.pptxJuc boston2014.pptx
Juc boston2014.pptx
 
Build & deploy PHP application (intro level)
Build & deploy PHP application (intro level)Build & deploy PHP application (intro level)
Build & deploy PHP application (intro level)
 
PHP Cloud Deployment Toolkits
PHP Cloud Deployment ToolkitsPHP Cloud Deployment Toolkits
PHP Cloud Deployment Toolkits
 
Symfony under control. Continuous Integration and Automated Deployments in Sy...
Symfony under control. Continuous Integration and Automated Deployments in Sy...Symfony under control. Continuous Integration and Automated Deployments in Sy...
Symfony under control. Continuous Integration and Automated Deployments in Sy...
 
Rock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment WorkflowsRock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment Workflows
 

Ähnlich wie DEPLOY PHP APPLICATIONS SAFELY, EFFICIENTLY AND FREQUENTLY

Improving QA on PHP projects - confoo 2011
Improving QA on PHP projects - confoo 2011Improving QA on PHP projects - confoo 2011
Improving QA on PHP projects - confoo 2011Michelangelo van Dam
 
What makes me "Grunt"?
What makes me "Grunt"? What makes me "Grunt"?
What makes me "Grunt"? Fabien Doiron
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php PresentationAlan Pinstein
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014biicode
 
Salesforce Admin's guide : the data loader from the command line
Salesforce Admin's guide : the data loader from the command lineSalesforce Admin's guide : the data loader from the command line
Salesforce Admin's guide : the data loader from the command lineCyrille Coeurjoly
 
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Bastian Feder
 
How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]Devon Bernard
 
Profiling PHP with Xdebug / Webgrind
Profiling PHP with Xdebug / WebgrindProfiling PHP with Xdebug / Webgrind
Profiling PHP with Xdebug / WebgrindSam Keen
 
Building com Phing - 7Masters PHP
Building com Phing - 7Masters PHPBuilding com Phing - 7Masters PHP
Building com Phing - 7Masters PHPiMasters
 
Continuous Integration with Scratchbox And CruiseControl
Continuous Integration with Scratchbox And CruiseControlContinuous Integration with Scratchbox And CruiseControl
Continuous Integration with Scratchbox And CruiseControlJani Mikkonen
 
Django dev-env-my-way
Django dev-env-my-wayDjango dev-env-my-way
Django dev-env-my-wayRobert Lujo
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPRobert Lemke
 
Scripting for infosecs
Scripting for infosecsScripting for infosecs
Scripting for infosecsnancysuemartin
 
"I have a framework idea" - Repeat less, share more.
"I have a framework idea" - Repeat less, share more."I have a framework idea" - Repeat less, share more.
"I have a framework idea" - Repeat less, share more.Fabio Milano
 
Asian Spirit 3 Day Dba On Ubl
Asian Spirit 3 Day Dba On UblAsian Spirit 3 Day Dba On Ubl
Asian Spirit 3 Day Dba On Ublnewrforce
 
How To Start Up With PHP In IBM i
How To Start Up With PHP In IBM iHow To Start Up With PHP In IBM i
How To Start Up With PHP In IBM iSam Pinkhasov
 

Ähnlich wie DEPLOY PHP APPLICATIONS SAFELY, EFFICIENTLY AND FREQUENTLY (20)

Write php deploy everywhere tek11
Write php deploy everywhere   tek11Write php deploy everywhere   tek11
Write php deploy everywhere tek11
 
Write php deploy everywhere
Write php deploy everywhereWrite php deploy everywhere
Write php deploy everywhere
 
Improving QA on PHP projects - confoo 2011
Improving QA on PHP projects - confoo 2011Improving QA on PHP projects - confoo 2011
Improving QA on PHP projects - confoo 2011
 
What makes me "Grunt"?
What makes me "Grunt"? What makes me "Grunt"?
What makes me "Grunt"?
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
 
Php Power Tools
Php Power ToolsPhp Power Tools
Php Power Tools
 
Salesforce Admin's guide : the data loader from the command line
Salesforce Admin's guide : the data loader from the command lineSalesforce Admin's guide : the data loader from the command line
Salesforce Admin's guide : the data loader from the command line
 
Improving qa on php projects
Improving qa on php projectsImproving qa on php projects
Improving qa on php projects
 
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
 
How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]
 
Profiling PHP with Xdebug / Webgrind
Profiling PHP with Xdebug / WebgrindProfiling PHP with Xdebug / Webgrind
Profiling PHP with Xdebug / Webgrind
 
Building com Phing - 7Masters PHP
Building com Phing - 7Masters PHPBuilding com Phing - 7Masters PHP
Building com Phing - 7Masters PHP
 
Continuous Integration with Scratchbox And CruiseControl
Continuous Integration with Scratchbox And CruiseControlContinuous Integration with Scratchbox And CruiseControl
Continuous Integration with Scratchbox And CruiseControl
 
Django dev-env-my-way
Django dev-env-my-wayDjango dev-env-my-way
Django dev-env-my-way
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHP
 
Scripting for infosecs
Scripting for infosecsScripting for infosecs
Scripting for infosecs
 
"I have a framework idea" - Repeat less, share more.
"I have a framework idea" - Repeat less, share more."I have a framework idea" - Repeat less, share more.
"I have a framework idea" - Repeat less, share more.
 
Asian Spirit 3 Day Dba On Ubl
Asian Spirit 3 Day Dba On UblAsian Spirit 3 Day Dba On Ubl
Asian Spirit 3 Day Dba On Ubl
 
How To Start Up With PHP In IBM i
How To Start Up With PHP In IBM iHow To Start Up With PHP In IBM i
How To Start Up With PHP In IBM i
 

Kürzlich hochgeladen

Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 

Kürzlich hochgeladen (20)

Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 

DEPLOY PHP APPLICATIONS SAFELY, EFFICIENTLY AND FREQUENTLY

  • 1. HOW TO DEPLOY PHP APPLICATIONS SAFELY, EFFICIENTLY, AND FREQUENTLY WITHOUT LOOSING YOUR SANITY (COMPLETELY) Created by Mihail Irintchev Head of Software Development SiteGround.com Web Hosting Co. /m.irintchev@siteground.com @irintchev
  • 2. ABOUT ME Name: Mihail Irintchev (Mike) From Sofia, Bulgaria Web developer since 2003 Work @ SiteGround Organizing @bgphp UG Love beer
  • 6. WHAT IS YOUR DEPLOYMENT PROCESS LIKE?
  • 7. OVERVIEW OF BUILD ESSENTIALS: Revision control system Continuous testing Continuous integration Staging environment Automatic documentation Code health metrics Deployment mechanism ... and you want all that plus more wrapped in ... AN AUTOMATED BUILD PROCEDURE!
  • 11. BASIC DISTINCTION BETWEEN VERSIONING SYSTEMS Local data model Distributed model SVN GIT CVS Bazaar darcs
  • 13. WHAT CAN THE VERSION CONTROL DO FOR YOU? (APART FROM STORING AND VERSIONING YOUR CODE) pre-commit and post-commit hooks
  • 14. 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 fi done
  • 15. ENFORCE CODE STANDARDS Run PHP_CodeSniffer (phpcs) Catch any serious violations (use levels) <?php echo "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
  • 16. PREVENT SOME FOOLISH MISTAKES ... like dumping DB user and pass on your home page ... or embarass yourself by leaving some other var_dump()/ print_r()/ var_export()behind
  • 18. SO JUST ADD ANOTHER SECTION TO THE PRE-COMMIT HOOK if [[ $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
  • 19. ANYTHING ELSE? YOUR IMAGINATION IS PRETTY MUCH THE BOUNDARY
  • 20. WHAT IS POST-COMMIT GOOD FOR? Automated logging Notifications
  • 21. THERE ARE OTHER HOOKS AS WELL SVN GIT pre-lock pre-unlock post-lock post-unlock start-commit pre-revprop-change post-revprop-change prepare-commit-msg post-merge pre-receive post-receive post-checkout pre-applypatch post-applypatch
  • 23. WHAT DOES PHING STAND FOR? PHing Is Not GNU make “It's a PHP project build system or build tool based on . You can do anything with it that you could do with a traditional build system like GNU make...” Apache Ant
  • 25. SERIOUSLY, WHY PHING? Very flexible and robust build tool Simple XML build file Variety of built-in and optional tasks Very easy to write your own custom task Good and community Platform independent No required external dependencies docs
  • 26. VERY EASY INSTALLATION Through PEAR: $ pear channel-discover pear.phing.info $ pear install [--alldeps] phing/phing Through Composer: { "require-dev": { "phing/phing": "2.*" } }
  • 27. 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 -->
  • 28. 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>
  • 29. TASK #2: UNIT-TESTS WHAT IS YOUR PHP UNIT-TESTING PREFERRED FRAMEWORK? By Sebastian Bergmann
  • 30. 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>
  • 31. TASK #3: JS UNIT-TESTS Your client-side code can be just as crucial as the server-side one, so why not test it continuously as well? THE TOOLS?
  • 32. 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 Martin Jonsson Qunit Phing Task
  • 33. TASK #4: AUTOMATIC DOCUMENTATION The tool: phpDocumentor 2 <phpdoc2 title="Gallery Documentation" destdir="docs" template="responsive-twig"> <fileset dir="./classes"> <include name="**/*.php" /> </fileset> </phpdoc2>
  • 34. CODE METRICS TASKS THE TOOLS? phpmd phpcpd pdepend phpcs Guess what? There exist ready-made phing tasks for all of them!
  • 35. TASKS #5: PHPMD Person 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>
  • 36. TASK #6: PHPCPD Person 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>
  • 37. TASK #7: PDEPEND Person 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>
  • 38. WHAT ELSE CAN YOU USE PHINGFOR? Encrypting/obfuscating code before deployment Generating static assets Generate and deploy static sites with tools like sculpin Execute post-deploy scripts Pretty much anything useful around the build/deploy
  • 39. TAKEAWAYS There 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
  • 40. CREDITS & REFERENCES "Quality Assurance for PHP Projects" by Michelangelo van Dam by Jordan Kasper"Browser Eyeballing != JavaScript Testing" The PHP Quality Assurance Toolchain