Voici un fichier build.xml qui me sert souvent de base pour automatiser mes builds php en intégration continue. Il n'est pas parfait, n'hésitez pas à proposer des améliorations ou proposer vos variantes / exemples, ils sont les bienvenus !

<?xml version="1.0" encoding="UTF-8"?>

<!-- vim: set expandtab tabstop=4 shiftwidth=4: -->

<project name="php" default="help">

    <!-- ================================================================== -->
    <!-- Properties                                                         -->
    <!-- ================================================================== -->
    
    <!-- *** Project General Properties *********************************** -->

    <property name="home"         value="${project.basedir}"/>
    <property name="src.dir"      value="library"/>
    <property name="test.dir"     value="tests"/>
    <property name="report.dir"   value="reports"/>
    <property name="doc.dir"      value="docs"/>
    <property name="context.dir"  value="contexts"/>
    <property name="config.dir"   value="config"/>
    <property name="convention"   value="PEAR"/>

    <!-- *** Project Custom Properties ************************************ -->

    <property file="${home}/${config.dir}/build.properties"   override="true"/>
    <property file="${home}/${config.dir}/${conf}.properties" override="true"/>

    <!-- *** Project Common Properties ************************************ -->

    <property name="package.name"   value="${application.name}"/>

    <!-- ================================================================== -->
    <!-- Targets                                                            -->
    <!-- ================================================================== -->

    <!-- *** $ phing help ************************************************* -->

    <target name        = "help"
            depends     = ""
            description = "Information about this build file">

        <echo>${package.name} Phing Build commands</echo>

    </target>

    <!-- *** $ phing inits ************************************************ -->

    <target name        = "inits"
            depends     = ""
            description = "Initializes the application environment">

        <!-- /library -->
        <mkdir dir="${home}/${src.dir}"/>

        <!-- /tests -->
        <mkdir dir="${home}/${test.dir}"/>
        <mkdir dir="${home}/${test.dir}/phpunit"/>
        <mkdir dir="${home}/${test.dir}/fitnesse"/>
        <mkdir dir="${home}/${test.dir}/selenium"/>
        <mkdir dir="${home}/${test.dir}/jsunit"/>

        <!-- /reports -->
        <mkdir dir="${home}/${report.dir}"/>
        <mkdir dir="${home}/${report.dir}/phpunit"/>
        <mkdir dir="${home}/${report.dir}/coverage"/>
        <mkdir dir="${home}/${report.dir}/codesniffer"/>

        <!-- /docs -->
        <mkdir dir="${home}/${doc.dir}"/>
        <mkdir dir="${home}/${doc.dir}/api"/>

        <!-- /contexts -->
        <mkdir dir="${home}/${context.dir}"/>

    </target>

    <!-- *** $ phing tests-unit ******************************************* -->

    <target name        = "tests-unit"
            depends     = "inits"
            description = "Executes unit tests (PHPUnit)">

        <php expression="require_once '${home}/${context.dir}/phpunit.php'"/>

        <phpunit2 haltonfailure="false" printsummary="true">
            <batchtest classpath="${home}/${src.dir}">
                <fileset dir="${home}">
                    <include name="${test.dir}/phpunit/**/*Test.php" />
                </fileset>
            </batchtest>
            <formatter type    = "xml"
                       todir   = "${home}/${report.dir}/phpunit"
                       outfile = "tests-report.xml" />
        </phpunit2>

        <phpunit2report
            infile = "${home}/${report.dir}/phpunit/tests-report.xml"
            format = "frames"
            todir  = "${home}/${report.dir}/phpunit" />

    </target>

    <!-- *** $ phing tests-unit-with-coverage ***************************** -->

    <target name        = "tests-unit-with-coverage"
            depends     = "inits"
            description = "Executes unit tests (PHPUnit), coverage (XDebug)">

        <php expression="require_once '${home}/${context.dir}/phpunit.php'"/>

        <coverage-setup database="${home}/${report.dir}/coverage/coverage.db">
            <fileset dir="${home}">
                <include name="${src.dir}/**/*.php" />
                <exclude name="${src.dir}/**/*Test.php" />
            </fileset>
        </coverage-setup>

        <phpunit2 haltonfailure = "false"
                  printsummary  = "true"
                  codecoverage  = "true">
            <batchtest classpath="${home}/${src.dir}">
                <fileset dir="${home}">
                    <include name="${test.dir}/**/*Test.php" />
                </fileset>
            </batchtest>
            <formatter type    = "xml"
                       todir   = "${home}/${report.dir}/phpunit"
                       outfile = "tests-report.xml" />
        </phpunit2>

        <coverage-report outfile="${home}/${report.dir}/coverage/coverage.db">
            <report todir="${home}/${report.dir}/coverage" />
        </coverage-report>

        <phpunit2report
            infile = "${home}/${report.dir}/phpunit/tests-report.xml"
            format = "frames"
            todir  = "${home}/${report.dir}/phpunit" />

    </target>

    <!-- *** $ phing tests-functional ************************************* -->

    <target name        = "tests-functional"
            depends     = "inits"
            description = "Executes functional tests (Fitnesse)">


    </target>

    <!-- *** $ phing tests-javascript ************************************* -->

    <target name        = "tests-javascript"
            depends     = "inits"
            description = "Executes javascript tests (JSUnit)">


    </target>

    <!-- *** $ phing tests-gui ******************************************** -->

    <target name        = "tests-gui"
            depends     = "inits"
            description = "Executes graphical user interface tests (Selenium)">


    </target>

    <!-- *** $ phing tests ************************************************ -->

    <target name        = "tests"
            depends     = "tests-unit-with-coverage,tests-functional,tests-javascript,tests-gui"
            description = "Generates all tests reports for project">



    </target>

    <!-- *** $ phing checks-convention ************************************ -->

    <target name        = "checks-convention"
            depends     = "inits"
            description = "Checks the quality of the code towards convention">
            
        <php expression="$cwd = getcwd()" returnProperty="cwd"/>

        <phpcs  outputFile   = "${home}/${report.dir}/codesniffer/checks-report.xml"
                standard     = "${convention}"
                showWarnings = "true"
                tabWidth     = "4"
                format       = "checkstyle">
                <fileset dir="${home}/${src.dir}">
                <include name="**/*.php" />
                <include name="**/*.phtml" />
            </fileset>
        </phpcs>

        <php expression="chdir('${cwd}')"/>
        
        <xslt file   = "${home}/${report.dir}/codesniffer/checks-report.xml"
              tofile = "${home}/${report.dir}/codesniffer/index.html"
              style  = "${home}/${config.dir}/codesniffer.xsl" />

    </target>

    <!-- *** $ phing checks-syntax **************************************** -->

    <target name        = "checks-syntax"
            depends     = "inits"
            description = "Checks the syntax of the code (Lint)">

        <phplint haltonfailure="true">
            <fileset dir="${home}">
                <include name="${src.dir}/**/*.php"/>
                <include name="${src.dir}/**/*.phtml"/>
            </fileset>
        </phplint>

    </target>

    <!-- *** $ phing checks *********************************************** -->

    <target name        = "checks"
            depends     = "checks-convention,checks-syntax"
            description = "Executes checking operations (convention,syntax)">



    </target>

    <!-- *** $ phing builds-on-commit ************************************* -->

    <target name        = "builds-on-commit"
            depends     = "tests-unit"
            description = "Continous integration Light-build on svn commit">



    </target>

    <!-- *** $ phing builds-nightly *************************************** -->

    <target name        = "builds-nightly"
            depends     = "tests,checks,docs"
            description = "Continuous integration full nightly-build">



    </target>

    <!-- *** $ phing docs-api ********************************************* -->

    <target name        = "docs-api"
            depends     = "inits"
            description = "Generates the PHPDocumentor API Documentation">

        <phpdoc title               = "${package.name} API Documentation"
                destdir             = "${home}/${doc.dir}/api"
                sourcecode          = "yes"
                output              = "HTML:Smarty:PHP"
                defaultcategoryname = "${package.name}"
                defaultpackagename  = "${package.name}">
            <fileset dir="${home}">
                <include name="${src.dir}/**" />
                <include name="${test.dir}/phpunit/**" />
                <include name="${test.dir}/fitnesse/**" />
            </fileset>
            <projdocfileset dir="${home}/${src.dir}">
            </projdocfileset>
        </phpdoc>

    </target>

    <!-- *** $ phing docs ************************************************* -->

    <target name        = "docs"
            depends     = "docs-api"
            description = "Generates all documentation for project">



    </target>
    
    <!-- *** $ phing deploys-testfunc ************************************* -->

    <target name        = "deploys-testfunc"
            depends     = "tests-unit"
            description = "Executes unit tests and deploys a tag of the application on functional tests platform">

        <echo>Deploying on functional tests platform...</echo>

        <echo>@todo: specific function tests platform pre-deployment tasks...</echo>

        <phingcall target="_template-deploys">
            <property name="${deploy.platform}" value="testfunc"/>
        </phingcall>
        
        <echo>@todo: specific functional tests platform post-deployment tasks...</echo>

        <echo>Application deployed on functional tests platform.</echo>

    </target>

    <!-- *** $ phing deploys-integ **************************************** -->

    <target name        = "deploys-integ"
            depends     = "tests-unit"
            description = "Executes unit tests and deploys a tag of the application on integration">

        <echo>Deploying on integration...</echo>

        <echo>@todo: specific integration pre-deployment tasks...</echo>

        <phingcall target="_template-deploys">
            <property name="${deploy.platform}" value="integ"/>
        </phingcall>
        
        <echo>@todo: specific integration post-deployment tasks...</echo>

        <echo>Application deployed on integration.</echo>

    </target>

    <!-- *** $ phing deploys-preprod ************************************** -->

    <target name        = "deploys-preprod"
            depends     = "tests-unit"
            description = "Executes unit tests and deploys a tag of the application on pre-production">

        <echo>Deploying on preproduction...</echo>

        <echo>@todo: specific preproduction pre-deployment tasks...</echo>

        <phingcall target="_template-deploys">
            <property name="${deploy.platform}" value="preprod"/>
        </phingcall>

        <echo>@todo: specific preproduction post-deployment tasks...</echo>

        <echo>Application deployed on preproduction.</echo>

    </target>

    <!-- *** $ phing deploys-prod ***************************************** -->

    <target name        = "deploys-prod"
            depends     = "tests-unit"
            description = "Executes unit tests and deploys a tag of the application on production">

        <echo>Deploying on production...</echo>

        <echo>@todo: specific production pre-deployment tasks...</echo>

        <phingcall target="_template-deploys">
            <property name="${deploy.platform}" value="prod"/>
        </phingcall>
        
        <echo>@todo: specific production post-deployment tasks...</echo>

        <echo>Application deployed on production.</echo>

    </target>

    <!-- *** internal task ************************************************ -->

    <target name        = "_template-deploys"
            depends     = "tests-unit"
            description = "Template - Executes unit tests and deploys a tag of the application on a platform">

        <if>
            <isnotset property="deploy.platform"/>
            <then>
                <fail>You must set the deploy.platform property with the name of the platform to deploy on</fail>
            </then>
        </if>

        <if>
            <isnotset property="tag"/>
            <then>
                <fail>You must provide a svn tag in order to deploy this tag on ${deploy.platform}</fail>
            </then>
        </if>

        <property file="${home}/${config.dir}/platforms/${deploy.platform}.properties" override="true" />

        <property name="deploy.src.dir" value="${home}/${build.dir}/${deploy.platform}/${tag}" />
        <property name="svn.url"        value="${svn.repo}/tags/${tag}" />

        <svnexport svnpath       = "${svn.bin}"
                   username      = "${svn.username}"
                   password      = "${svn.password}"
                   force         = "true"
                   nocache       = "true"
                   repositoryurl = "${svn.url}"
                   todir         = "${deploy.src.dir}"/>
        
        <echo>@todo : deployment (zip ${deploy.src.dir, then ftp, ...) </echo>

        <fail>@remove: Not yet implemented</fail>

    </target>

</project>