Slides of the talk that I gave during PHP Johannesburg 2014
https://joind.in/talk/view/10411
Manually creating builds and running deployments can be scary, tedious, error-prone, boring, stressful (check all that apply). What you need is a tool that helps automate the necessary steps to build, test, package and deploy your app.
During this talk you will be introduced to the workings of Phing, it's rich set of out-of-the-box tasks and easy extensibility. Step by step, you will learn how to write a comprehensive deployment script. A number of demonstrations will cover testing, packaging, database migration, continuous integration, multi-server deployments and other real-world use cases.
15. What is Phing?
• “PHing Is Not GNU make; it's a PHP project build system
or build tool based on Apache Ant.”
• XML build files
• Mostly cross-platform
• Integrates various popular (PHP) tools
• Lots. Of. Tasks.
20. Build file
• XML
• Contains standard elements
• Task: performs a specific function (copy, git commit, etc.)
• Target: collection of tasks, can optionally depend on other
targets
• Project: root node, contains multiple targets
30. Conditions
<if>
<equals arg1="${foo}" arg2="bar" />
<then>
<echo message="The value of property foo is bar" />
</then>
<else>
<echo message="The value of property foo is not bar" />
</else>
</if>
37. PHPUnit
• Built-in support for most configuration options
• Gathers code coverage information
• Various output formats / reports
• PHPUnit 4.x support soon!
38. PHPUnit
• Stop the build when a test fails
<phpunit haltonfailure="true" haltonerror="true"
bootstrap="my_bootstrap.php" printsummary="true">
<batchtest>
<fileset dir="src">
<include name="**/*Test.php"/>
</fileset>
</batchtest>
</phpunit>
Buildfile: /home/michiel/phpunit/build.xml
Demo > test:
[phpunit] Total tests run: 1, Failures: 1, Errors: 0,
Incomplete: 0, Skipped: 0, Time elapsed: 0.00591 s
Execution of target "test" failed for the following reason:
/home/michiel/phpunit/build.xml:3:44: Test FAILURE (testSayHello in
class HelloWorldTest): Failed asserting that two strings are equal.
39. PHPUnit example
• Determine which files to include in the coverage report
<coverage-setup database="reports/coverage.db">
<fileset dir="src">
<include name="**/*.php"/>
<exclude name="**/*Test.php"/>
</fileset>
</coverage-setup>
• Gather code coverage and other data during the test run
<phpunit codecoverage="true">
<formatter type="xml" todir="reports"/>
<batchtest>
<fileset dir="src">
<include name="**/*Test.php"/>
</fileset>
</batchtest>
</phpunit>
40. PHPUnit example
• Generate some reports
<phpunitreport infile="reports/testsuites.xml"
format="frames" todir="reports/tests"/>
<coverage-report outfile="reports/coverage.xml">
<report todir="reports/coverage" title="Demo"/>
</coverage-report>
41. Documentation
• Phing currently integrates with popular documentation
tools
• phpDocumentor (2)
• ApiGen
• Also supports r(e)ST (reStructuredText)
<phpdoc2 title="Phing API Documentation" output="docs">
<fileset dir="../../classes">
<include name="**/*.php"/>
</fileset>
</phpdoc2>
59. Symbolic links
• All releases stored in separate directories
• Symlink "current" to latest release
• Allows for easy (code) rollbacks
<echo>Creating symbolic link</echo>
<ssh ...
command="cd ${deploy.location.project};
if [ -h "current" ]; then
rm -f previous; mv current previous; fi;
ln -s ${build.release} current" />
60. Database migration
• Set of delta SQL files (1-create-post.sql)
• Tracks current version of your db in changelog table
• Generates do and undo SQL files
CREATE TABLE changelog (
change_number BIGINT NOT NULL,
delta_set VARCHAR(10) NOT NULL,
start_dt TIMESTAMP NOT NULL,
complete_dt TIMESTAMP NULL,
applied_by VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL
)
61. Database migration
• Delta scripts with do (up) & undo (down) parts
--//
CREATE TABLE `post` (
`title` VARCHAR(255),
`time_created` DATETIME,
`content` MEDIUMTEXT
);
--//@UNDO
DROP TABLE `post`;
--//
63. Database migration
-- Fragment begins: 1 --
INSERT INTO changelog
(change_number, delta_set, start_dt, applied_by, description)
VALUES (1, 'Main', NOW(), 'dbdeploy',
'1-create_initial_schema.sql');
--//
CREATE TABLE `post` (
`title` VARCHAR(255),
`time_created` DATETIME,
`content` MEDIUMTEXT
);
UPDATE changelog
SET complete_dt = NOW()
WHERE change_number = 1
AND delta_set = 'Main';
-- Fragment ends: 1 --
64. Database migration
-- Fragment begins: 1 --
DROP TABLE `post`;
--//
DELETE FROM changelog
WHERE change_number = 1
AND delta_set = 'Main';
-- Fragment ends: 1 --
68. Writing your own task
• Extend from Task
• Contains main() method and optionally init()
• Setter method for each attribute in the build file
69. Our new task should
• Accept filesets
• Count number of lines in each file
• Fail the build if a file with zero lines is found
70. Our new task
<?php
require_once 'phing/Task.php';
class CountLinesTask extends Task
{
public function main()
{
$foundEmpty = false;
if ($foundEmpty) {
throw new BuildException("One or more files have zero lines");
}
}
}
71. Injecting file sets
private $_filesets = array();
/**
* Creator for _filesets
*
* @return FileSet
*/
public function createFileset()
{
$num = array_push($this->_filesets, new FileSet());
return $this->_filesets[$num-1];
}
74. Using the task
Buildfile: /home/michiel/examples/count.xml
Count Lines > count:
[countlines] /home/michiel/examples/empty.txt: 0 line(s)
[countlines] /home/michiel/examples/lines.txt: 3 line(s)
Execution of target "count" failed for the following reason:
/home/michiel/examples/count.xml:7:20: One or more files have zero lines
BUILD FAILED
/home/michiel/examples/count.xml:7:20: One or more files have zero lines
Total time: 0.0454 seconds
75. Alternative: Ad Hoc
<target name="main">
<adhoc-task name="foo"><![CDATA[
class FooTask extends Task {
private $bar;
public function setBar($bar) {
$this->bar = $bar;
}
public function main() {
$this->log("In main(): " . $this->bar);
}
}
]]></adhoc-task>
<foo bar="TEST"/>
</target>
76.
77. Where to go from here
• Tool versions
• Performance
• Documentation
• PHP 5.3/5.4/5.5
• IDE support
• CI integration
78. Questions?
Example code at https://github.com/mrook/phing-examples
Please leave feedback at https://joind.in/10411
Contact us on:
http://www.phing.info
#phing (freenode)
@phingofficial
Thank you!