Real-World Strategies for Continuous Delivery
          with Maven and Jenkins




                          John Ferguson Smart
Consulta
                    nt
            Trainer
           Mentor
           Author
          Speaker
          Coder
John Fer
         guson S
                 mar t
Continuous Delivery

 Getting value to the business.
             Fast.




                       3
But what is Continuous Delivery?
     A build tool?

                     A CI tool?

                      Automated tests?



       Automated quality?

            Automated deployment?
Yes...and No
Continuous Delivery is an attitude
Deliver business value more frequently
Value can also come in the form of fast feedback
Give power back to the business
The ‘eternal beta’ strategy
Principles of Continuous
        Delivery
Principle #1

Every build is a potential release
Principle #2

Eliminate manual bottlenecks
Principle #3

Automate wherever possible
Principle #4
Have automated tests you can
           trust
Build Pipelines




The conveyer belts of Continuous Delivery
Compile and unit test


 Package and deploy


                        DEV
  Acceptance tests


   Deploy to QA               QA




 Deploy to PROD
                          PROD
Compile and unit test


Each commit is a potential release
    Package and deploy


                                     DEV
     Acceptance tests


      Deploy to QA                         QA




     Deploy to PROD
                                       PROD
Compile and unit test


          Package and deploy


                                 DEV
           Acceptance tests
We reuse the same binaries


            Deploy to QA               QA




           Deploy to PROD
                                   PROD
Compile and unit test


                Package and deploy


                                                  DEV
                 Acceptance tests


Automated tests give us confidence in our build
                  Deploy to QA                          QA




                 Deploy to PROD
                                                    PROD
Compile and unit test


     Package and deploy


                            DEV
      Acceptance tests

Automated, repeatable
    deployments QA
       Deploy to                  QA




      Deploy to PROD
                              PROD
Continuous Delivery with Maven




      Why does it have to be so hard?!
The Maven lifecycle

          compile
        test-compile
             test
          package
       integration-test
            verify
            install
           deploy
The Maven lifecycle

Compile and unit test    mvn test        compile
                                       test-compile
                                            test

 Integration tests      mvn verify           compile
                                           test-compile
                                                test
                                               package
                                           integration-test
                                                 verify
The Maven lifecycle

Compile and unit test   mvn test       compile
                                     test-compile
                                          test
                                          compile
                                        test-compile
  Integration tests     mvn verify            test
                                            package
                                         integration-test
                                               verify

Deploy to repository                      compile
                        mvn deploy
                                        test-compile
                                             test
                                            package
                                        integration-test
                                             verify
                                              deploy
The Maven Release Process


              1.0.0-SNAPSHOT




              1.0.0-SNAPSHOT

                           mvn release

                   1.0.0
The Maven Release Process

              mvn release:prepare
• Check that there are no uncommitted changes in the sources
• Check that there are no SNAPSHOT dependencies
• Change the version in the POMs from x-SNAPSHOT to a new version (you
  will be prompted for the versions to use)
• Transform the SCM information in the POM to include the final destination
  of the tag
• Run the project tests against the modified POMs to confirm everything is in
  working order
• Commit the modified POMs
• Tag the code in the SCM with a version name (this will be prompted for)
• Bump the version in the POMs to a new value y-SNAPSHOT (these values
  will also be prompted for)
• Commit the modified POMs
The Maven Release Process

       mvn release:prepare

  compile
test-compile
     test
    package          1.0.0
 integration-test
       verify       1.0.1-SNAPSHOT

1.0.0-SNAPSHOT
   1.0.1-SNAPSHOT
The Maven Release Process

 mvn release:perform
                    compile
                  test-compile
                       test
       1.0.0          package
                   integration-test
                         verify
                         install
                          deploy
                       1.0.0
The Maven Release Process


Maven: You build a new release when
a snapshot build is good enough




                          Continuous Delivery: Any
                          build is a potential release
Options?




Make Maven work for you
Beware duplication!
Build and unit test

           mvn test


    Integration tests

                mvn verify

      Code coverage...

                 mvn site
Minimize build jobs for the main build
      Default build

            mvn install
                       compile
                          test
                     integration-test
                            verify
                             install
Split unit and integration tests
                <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-surefire-plugin</artifactId>
                     <version>2.11</version>
                     <configuration>
                         <skip>true</skip>
                     </configuration>
                     <executions>
                         <execution>
                             <id>unit-tests</id>
                             <phase>test</phase>
                             <goals>
                                 <goal>test</goal>
                             </goals>
                             <configuration>
                                 <skip>false</skip>
                                 <includes>
                                     <include>**/When*.*</include>
                                 </includes>
                                 <excludes>
                                     <exclude>%regex[.*integration.*When.*]</exclude>
                                 </excludes>
                             </configuration>
                         </execution>
                         <execution>
                             <id>integration-tests</id>
                             <phase>integration-test</phase>
                             <goals>
                                 <goal>test</goal>
                             </goals>
                             <configuration>
                                 <skip>false</skip>
                                 <includes>
                                     <include>%regex[.*integration.*]</include>
                                 </includes>
                             </configuration>
                         </execution>


                           Using package conventions
                     </executions>
                 </plugin>
Split unit and integration tests
                <groupId>org.apache.maven.plugins</groupId>
                            <plugin>
                                 <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                                 <artifactId>maven-surefire-plugin</artifactId>
                <version>2.11</version>
                                 <version>2.11</version>
                <configuration>
                                 <configuration>
                                     <skip>true</skip>
                    <skip>true</skip>
                                 </configuration>
                </configuration>
                                 <executions>
                                         <execution>
                                             <id>unit-tests</id>
                                             <phase>test</phase>
                                             <goals>
                                                 <goal>test</goal>
                                             </goals>
                                             <configuration>
                                                 <skip>false</skip>
                                                 <includes>
                                                     <include>**/When*.*</include>
                                                 </includes>
                                                 <excludes>
                                                     <exclude>%regex[.*integration.*When.*]</exclude>
                                                 </excludes>
                                             </configuration>
                                         </execution>
                                         <execution>
                                             <id>integration-tests</id>
                                             <phase>integration-test</phase>
                                             <goals>
                                                 <goal>test</goal>
                                             </goals>
                                             <configuration>
                                                 <skip>false</skip>
                                                 <includes>
                                                     <include>%regex[.*integration.*]</include>
                                                 </includes>
                                             </configuration>
                                         </execution>


                                           Using package conventions
                                     </executions>
                                 </plugin>
Split unit and integration tests
                      <plugin>
                           <groupId>org.apache.maven.plugins</groupId>
                           <artifactId>maven-surefire-plugin</artifactId>
                    <execution>
                           <version>2.11</version>
                           <configuration>
                        <id>unit-tests</id>
                               <skip>true</skip>
                        <phase>test</phase>
                           </configuration>
                        <goals>
                           <executions>
                               <execution>
                            <goal>test</goal>
                                   <id>unit-tests</id>
                        </goals>
                                   <phase>test</phase>
                                   <goals>
                        <configuration>
                                       <goal>test</goal>
                            <skip>false</skip>
                                   </goals>
                            <includes>
                                   <configuration>
                                       <skip>false</skip>
                                <include>**/When*.*</include>
                                       <includes>
                            </includes>
                                           <include>**/When*.*</include>
                            <excludes>
                                       </includes>
                                       <excludes>
                                <exclude>%regex[.*integration.*When.*]</exclude>
                                           <exclude>%regex[.*integration.*When.*]</exclude>
                            </excludes>
                                       </excludes>
                                   </configuration>
                        </configuration>
                               </execution>
                    </execution>
                               <execution>
                                   <id>integration-tests</id>

                Excluding integration tests from the test phase
                                   <phase>integration-test</phase>
                                   <goals>
                                       <goal>test</goal>
                                   </goals>
                                   <configuration>
                                       <skip>false</skip>
                                       <includes>
                                           <include>%regex[.*integration.*]</include>
                                       </includes>
                                   </configuration>
                               </execution>


                             Using package conventions
                           </executions>
                       </plugin>
Split unit and integration tests
                      <plugin>
                           <groupId>org.apache.maven.plugins</groupId>
                           <artifactId>maven-surefire-plugin</artifactId>
                           <version>2.11</version>
                           <configuration>
                               <skip>true</skip>
                           </configuration>
                           <executions>
                               <execution>
                                   <id>unit-tests</id>

Run only integration tests in the integration-test phase
                                   <phase>test</phase>
                                   <goals>
                                       <goal>test</goal>
                                   </goals>
                      <execution>
                                   <configuration>
                          <id>integration-tests</id>
                                       <skip>false</skip>
                                       <includes>
                          <phase>integration-test</phase>
                                           <include>**/When*.*</include>
                          <goals>
                                       </includes>
                              <goal>test</goal>
                                       <excludes>
                                           <exclude>%regex[.*integration.*When.*]</exclude>
                          </goals>
                                       </excludes>
                          <configuration>
                                   </configuration>
                              <skip>false</skip>
                               </execution>
                               <execution>
                              <includes>
                                   <id>integration-tests</id>
                                  <include>%regex[.*integration.*]</include>
                                   <phase>integration-test</phase>
                                   <goals>
                              </includes>
                                       <goal>test</goal>
                          </configuration>
                                   </goals>
                      </execution>
                                   <configuration>
                                       <skip>false</skip>
                                       <includes>
                                           <include>%regex[.*integration.*]</include>
                                       </includes>
                                   </configuration>
                               </execution>


                              Using package conventions
                           </executions>
                       </plugin>
Compile
Default build
                       Unit Test
       mvn deploy
                       Package

                    Integration Test
Compile
Default build
                                      Unit Test
      mvn install
                                      Package

                                 Integration Test




         Jenkins Artifactory Plugin
Compile
Default build
                            Unit Test
      mvn install
                            Package

                         Integration Test




     mvn deploy:deploy
Eliminate waste
Run code coverage with the integration tests

                                            compile
                                          test-compile
 Integration tests    mvn verify                test
                                              package
                                           integration-test
                                                 verify

  Test coverage       mvn cobertura
                                           compile
                                         test-compile
       Duplication!                            test
                                             package
                                          integration-test
                                              cobertura

     Creates its own instrumented JAR files
JACOCO
Java Code Coverage




 Code coverage on the fly

Doesn’t mess with your JAR files
Run code coverage with the integration tests
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.5.10.201208310627</version>
    <executions>
        <execution>
            <id>jacoco-initialize</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>                Measure code coverage
        </execution>                after the integration tests
        <execution>
            <id>jacoco-site</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>
 	
  	
  	
  	
  	
  <plugin>
Run code coverage with the integration tests
	
  	
  	
  	
  	
  	
  	
  	
  <groupId>org.jacoco</groupId>
	
  	
  	
  	
  	
  	
  	
  	
  <artifactId>jacoco-­‐maven-­‐plugin</artifactId>
	
  	
  	
  	
  	
  	
  	
  	
  <executions>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <execution>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <goals>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <goal>prepare-­‐agent</goal>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  </goals>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  </execution>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <execution>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <id>check</id>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <goals>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <goal>check</goal>             Define minimum   coverage
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  </goals>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <phase>post-­‐integration-­‐test</phase>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <configuration>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <check>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <classRate>95</classRate>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <instructionRate>95</instructionRate>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <methodRate>90</methodRate>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <branchRate>95</branchRate>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <complexityRate>95</complexityRate>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  <lineRate>95</lineRate>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  </check>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  </configuration>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  </execution>
Run code coverage with the integration tests

Integration tests/test                        compile
                                            test-compile
                         mvn install              test
      coverage                                  package
                                             integration-test
                                                   verify

                                       Uninstrumented JAR


          Coverage checks and report
Minimal overhead
Build Time




             Normal build   With JaCoCo
Reuse binaries wherever possible

   Default build


                                   1.0.203
Deploy to TEST



Acceptance Tests
                                 1.0.201
                             1.0.202
                        1.0.203
Deploy to UAT
Have a separate acceptance test suite



    Acceptance Tests


                                    TEST



                              UAT

                       PROD
Take code quality seriously




                        Checkstyle


             Findbugs
Take code quality seriously
Code quality metrics

            mvn site
Take code quality seriously
                         Pick and choose your metrics
Code quality metrics

        mvn pmd:check
         mvn findbugs:check
          mvn checkstye:checkstyle
               Fail the build if there are violations
Avoid the Maven Release Plugin




Don’t sweat the version numbers
Developers always work on a SNAPSHOT version



                  1.0-SNAPSHOT




                   This number is pretty arbitrary
Jenkins sets a release candidate version at the
           start of the build pipeline


                   1.0-SNAPSHOT



                       1.0.203




        This number is a build counter
This version goes through the build pipeline


                   1.0.203


                  Unit tests

              Acceptance tests


            Code quality metrics


               Deploy to TEST
This version goes through the build pipeline


                   1.0.203
                     1.0.204
                       1.0.205


                  Unit tests
                Acceptance tests
                Code quality metrics
                   Deploy to TEST
                   Acceptance Tests


                            1.0.203
                                      1.0.204
                                                1.0.205
Create a new release branch

                  Update the version number

                  Build and test release candidate


                              Did
                           it work?
                    No                  Yes

Drop release branch              Push release branch

Notify everyone                  Deploy release candidate
Create a new release branch

                  Update the version number

                  Build and test release candidate 1.0.203


                              Did
                           it work?
                    No                  Yes

Drop release branch              Push release branch

Notify everyone                  Deploy release candidate
Create a new release branch

                  Update the version number

                                   Versions Plugin
                  Build and test release candidate

                   mvn versions:set -DnewVersion=1.0.203
                              Did
                           it work?
                    No                 Yes

Drop release branch             Push release branch

Notify everyone                 Deploy release candidate
Create a new release branch

                  Update the version number

                  Build and test release candidate


                               Did
                   mvn   verify ...
                            it work?
                    No                  Yes

Drop release branch              Push release branch

Notify everyone                  Deploy release candidate
And make it visible

            The Build Pipeline plugin
Let’s see it in action!



                 TEST
                        UAT
                              PROD

       Jenkins
Let’s see it in action!
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat

                 acceptance-tests

deploy-to-prod
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat

                 acceptance-tests

deploy-to-prod
initial-build




         Links to binary artifacts in Artifactory
Release candidate number
initial-build




Links to binary artifacts in Artifactory
initial-build

   Use a parameterized build to
   configure the major build version




    Users can override the default
    major version
initial-build

                Create a new branch




Update the version in the pom files




       Build the binaries
initial-build

       Conditional build step plugin




          If the build succeeds...




   Commit the changes and push
   the branch to the repository
initial-build




                If the build fails...




         Delete the branch
initial-build




Deploy the release candidate to Artifactory
initial-build

       Deploy to the test environment




                     Target platform
initial-build


<plugin>
    <groupId>com.jelastic</groupId>
    <artifactId>jelastic-maven-plugin</artifactId>
    <version>1.6</version>
    <configuration>
         <email>${jelastic.username}</email>
         <password>${jelastic.password}</password>
         <context>${jelastic.context}</context>
         <environment>${jelastic.environment}</environment>
         <api_hoster>app.jelastic.servint.net</api_hoster>
    </configuration>
</plugin>
initial-build




                 Archive binary
Update the build description
initial-build




                 Archive binary




Pass the release branch to the next build job
initial-build




Don’t start a new build pipeline if
one is currently running.
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat

                 acceptance-tests

deploy-to-prod
initial-build


             code-quality
Pass in the release we want to build against
           deploy-to-test

                              acceptance-tests

           deploy-to-uat

                             acceptance-tests

           deploy-to-prod
initial-build


      code-quality


     deploy-to-test
Build from the release candidate branch
                        acceptance-tests

     deploy-to-uat

                       acceptance-tests

     deploy-to-prod
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat

                 acceptance-tests

deploy-to-prod
initial-build


     code-quality
Copy the WAR file from the initial build

   deploy-to-test

                      acceptance-tests

   deploy-to-uat

                     acceptance-tests

   deploy-to-prod
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat
          ...deploy this WAR file
                 acceptance-tests

deploy-to-prod
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat

                 acceptance-tests

deploy-to-prod the acceptance tests
      ...and run
initial-build


                   code-quality


                  deploy-to-test

                                    acceptance-tests

                  deploy-to-uat
What platform do we run the acceptance test against

                                   acceptance-tests

                  deploy-to-prod
initial-build


                   code-quality


                  deploy-to-test

                                    acceptance-tests

                  deploy-to-uat
What platform do we run the acceptance test against

                                   acceptance-tests

                  deploy-to-prod
initial-build


 code-quality


deploy-to-test

                  acceptance-tests

deploy-to-uat

                 acceptance-tests

deploy-to-prod
initial-build


                   code-quality


                  deploy-to-test

                                    acceptance-tests

                  deploy-to-uat
What platform do we run the acceptance test against

                                   acceptance-tests

                  deploy-to-prod
initial-build


                   code-quality


                  deploy-to-test

                                    acceptance-tests

                  deploy-to-uat
What platform do we run the acceptance test against

                                   acceptance-tests

                  deploy-to-prod
initial-build


   code-quality


  deploy-to-test

                    acceptance-tests

  deploy-to-uat
Build promotion status
                   acceptance-tests

 deploy-to-prod
initial-build
Copy the WAR file from the initial build...


                 code-quality


                deploy-to-test

                                  acceptance-tests

                deploy-to-uat
           ...and deploy it to UAT

                                 acceptance-tests

               deploy-to-prod
A build promotioninitial-build deploy to production
                  process to


                 code-quality


                deploy-to-test

                                  acceptance-tests

                deploy-to-uat

                                 acceptance-tests

                deploy-to-prod
A build promotioninitial-build deploy to production
                  process to


                 code-quality


                deploy-to-test

                                  acceptance-tests

                deploy-to-uat

                                 acceptance-tests

                deploy-to-prod
Build pipeline for an overview of the process
Thank You




                     John	
  Ferguson	
  Smart
      Email:	
  john.smart@wakaleo.com
       Web:	
  hHp://www.wakaleo.com
                         TwiHer:	
  wakaleo

Continuous delivery-with-maven

  • 1.
    Real-World Strategies forContinuous Delivery with Maven and Jenkins John Ferguson Smart
  • 2.
    Consulta nt Trainer Mentor Author Speaker Coder John Fer guson S mar t
  • 3.
    Continuous Delivery Gettingvalue to the business. Fast. 3
  • 4.
    But what isContinuous Delivery? A build tool? A CI tool? Automated tests? Automated quality? Automated deployment?
  • 5.
  • 6.
  • 7.
    Deliver business valuemore frequently
  • 8.
    Value can alsocome in the form of fast feedback
  • 9.
    Give power backto the business
  • 10.
  • 11.
  • 12.
    Principle #1 Every buildis a potential release
  • 13.
  • 14.
  • 15.
    Principle #4 Have automatedtests you can trust
  • 16.
    Build Pipelines The conveyerbelts of Continuous Delivery
  • 17.
    Compile and unittest Package and deploy DEV Acceptance tests Deploy to QA QA Deploy to PROD PROD
  • 18.
    Compile and unittest Each commit is a potential release Package and deploy DEV Acceptance tests Deploy to QA QA Deploy to PROD PROD
  • 19.
    Compile and unittest Package and deploy DEV Acceptance tests We reuse the same binaries Deploy to QA QA Deploy to PROD PROD
  • 20.
    Compile and unittest Package and deploy DEV Acceptance tests Automated tests give us confidence in our build Deploy to QA QA Deploy to PROD PROD
  • 21.
    Compile and unittest Package and deploy DEV Acceptance tests Automated, repeatable deployments QA Deploy to QA Deploy to PROD PROD
  • 22.
    Continuous Delivery withMaven Why does it have to be so hard?!
  • 23.
    The Maven lifecycle compile test-compile test package integration-test verify install deploy
  • 24.
    The Maven lifecycle Compileand unit test mvn test compile test-compile test Integration tests mvn verify compile test-compile test package integration-test verify
  • 25.
    The Maven lifecycle Compileand unit test mvn test compile test-compile test compile test-compile Integration tests mvn verify test package integration-test verify Deploy to repository compile mvn deploy test-compile test package integration-test verify deploy
  • 26.
    The Maven ReleaseProcess 1.0.0-SNAPSHOT 1.0.0-SNAPSHOT mvn release 1.0.0
  • 27.
    The Maven ReleaseProcess mvn release:prepare • Check that there are no uncommitted changes in the sources • Check that there are no SNAPSHOT dependencies • Change the version in the POMs from x-SNAPSHOT to a new version (you will be prompted for the versions to use) • Transform the SCM information in the POM to include the final destination of the tag • Run the project tests against the modified POMs to confirm everything is in working order • Commit the modified POMs • Tag the code in the SCM with a version name (this will be prompted for) • Bump the version in the POMs to a new value y-SNAPSHOT (these values will also be prompted for) • Commit the modified POMs
  • 28.
    The Maven ReleaseProcess mvn release:prepare compile test-compile test package 1.0.0 integration-test verify 1.0.1-SNAPSHOT 1.0.0-SNAPSHOT 1.0.1-SNAPSHOT
  • 29.
    The Maven ReleaseProcess mvn release:perform compile test-compile test 1.0.0 package integration-test verify install deploy 1.0.0
  • 30.
    The Maven ReleaseProcess Maven: You build a new release when a snapshot build is good enough Continuous Delivery: Any build is a potential release
  • 31.
  • 32.
    Beware duplication! Build andunit test mvn test Integration tests mvn verify Code coverage... mvn site
  • 33.
    Minimize build jobsfor the main build Default build mvn install compile test integration-test verify install
  • 34.
    Split unit andintegration tests            <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-surefire-plugin</artifactId>                 <version>2.11</version>                 <configuration>                     <skip>true</skip>                 </configuration>                 <executions>                     <execution>                         <id>unit-tests</id>                         <phase>test</phase>                         <goals>                             <goal>test</goal>                         </goals>                         <configuration>                             <skip>false</skip>                             <includes>                                 <include>**/When*.*</include>                             </includes>                             <excludes>                                 <exclude>%regex[.*integration.*When.*]</exclude>                             </excludes>                         </configuration>                     </execution>                     <execution>                         <id>integration-tests</id>                         <phase>integration-test</phase>                         <goals>                             <goal>test</goal>                         </goals>                         <configuration>                             <skip>false</skip>                             <includes>                                 <include>%regex[.*integration.*]</include>                             </includes>                         </configuration>                     </execution> Using package conventions                 </executions>             </plugin>
  • 35.
    Split unit andintegration tests                 <groupId>org.apache.maven.plugins</groupId>            <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-surefire-plugin</artifactId>                 <artifactId>maven-surefire-plugin</artifactId>                 <version>2.11</version>                 <version>2.11</version>                 <configuration>                 <configuration>                     <skip>true</skip>                     <skip>true</skip>                 </configuration>                 </configuration>                 <executions>                     <execution>                         <id>unit-tests</id>                         <phase>test</phase>                         <goals>                             <goal>test</goal>                         </goals>                         <configuration>                             <skip>false</skip>                             <includes>                                 <include>**/When*.*</include>                             </includes>                             <excludes>                                 <exclude>%regex[.*integration.*When.*]</exclude>                             </excludes>                         </configuration>                     </execution>                     <execution>                         <id>integration-tests</id>                         <phase>integration-test</phase>                         <goals>                             <goal>test</goal>                         </goals>                         <configuration>                             <skip>false</skip>                             <includes>                                 <include>%regex[.*integration.*]</include>                             </includes>                         </configuration>                     </execution> Using package conventions                 </executions>             </plugin>
  • 36.
    Split unit andintegration tests            <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-surefire-plugin</artifactId>                     <execution>                 <version>2.11</version>                 <configuration>                         <id>unit-tests</id>                     <skip>true</skip>                         <phase>test</phase>                 </configuration>                         <goals>                 <executions>                     <execution>                             <goal>test</goal>                         <id>unit-tests</id>                         </goals>                         <phase>test</phase>                         <goals>                         <configuration>                             <goal>test</goal>                             <skip>false</skip>                         </goals>                             <includes>                         <configuration>                             <skip>false</skip>                                 <include>**/When*.*</include>                             <includes>                             </includes>                                 <include>**/When*.*</include>                             <excludes>                             </includes>                             <excludes>                                 <exclude>%regex[.*integration.*When.*]</exclude>                                 <exclude>%regex[.*integration.*When.*]</exclude>                             </excludes>                             </excludes>                         </configuration>                         </configuration>                     </execution>                     </execution>                     <execution>                         <id>integration-tests</id> Excluding integration tests from the test phase                         <phase>integration-test</phase>                         <goals>                             <goal>test</goal>                         </goals>                         <configuration>                             <skip>false</skip>                             <includes>                                 <include>%regex[.*integration.*]</include>                             </includes>                         </configuration>                     </execution> Using package conventions                 </executions>             </plugin>
  • 37.
    Split unit andintegration tests            <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-surefire-plugin</artifactId>                 <version>2.11</version>                 <configuration>                     <skip>true</skip>                 </configuration>                 <executions>                     <execution>                         <id>unit-tests</id> Run only integration tests in the integration-test phase                         <phase>test</phase>                         <goals>                             <goal>test</goal>                         </goals>                     <execution>                         <configuration>                         <id>integration-tests</id>                             <skip>false</skip>                             <includes>                         <phase>integration-test</phase>                                 <include>**/When*.*</include>                         <goals>                             </includes>                             <goal>test</goal>                             <excludes>                                 <exclude>%regex[.*integration.*When.*]</exclude>                         </goals>                             </excludes>                         <configuration>                         </configuration>                             <skip>false</skip>                     </execution>                     <execution>                             <includes>                         <id>integration-tests</id>                                 <include>%regex[.*integration.*]</include>                         <phase>integration-test</phase>                         <goals>                             </includes>                             <goal>test</goal>                         </configuration>                         </goals>                     </execution>                         <configuration>                             <skip>false</skip>                             <includes>                                 <include>%regex[.*integration.*]</include>                             </includes>                         </configuration>                     </execution> Using package conventions                 </executions>             </plugin>
  • 38.
    Compile Default build Unit Test mvn deploy Package Integration Test
  • 39.
    Compile Default build Unit Test mvn install Package Integration Test Jenkins Artifactory Plugin
  • 40.
    Compile Default build Unit Test mvn install Package Integration Test mvn deploy:deploy
  • 41.
  • 42.
    Run code coveragewith the integration tests compile test-compile Integration tests mvn verify test package integration-test verify Test coverage mvn cobertura compile test-compile Duplication! test package integration-test cobertura Creates its own instrumented JAR files
  • 43.
    JACOCO Java Code Coverage Code coverage on the fly Doesn’t mess with your JAR files
  • 44.
    Run code coveragewith the integration tests <plugin>     <groupId>org.jacoco</groupId>     <artifactId>jacoco-maven-plugin</artifactId>     <version>0.5.10.201208310627</version>     <executions>         <execution>             <id>jacoco-initialize</id>             <goals>                 <goal>prepare-agent</goal>             </goals> Measure code coverage         </execution> after the integration tests         <execution>             <id>jacoco-site</id>             <phase>post-integration-test</phase>             <goals>                 <goal>report</goal>             </goals>         </execution>     </executions> </plugin>
  • 45.
               <plugin> Run code coverage with the integration tests                <groupId>org.jacoco</groupId>                <artifactId>jacoco-­‐maven-­‐plugin</artifactId>                <executions>                    <execution>                        <goals>                            <goal>prepare-­‐agent</goal>                        </goals>                    </execution>                    <execution>                        <id>check</id>                        <goals>                            <goal>check</goal> Define minimum coverage                        </goals>                        <phase>post-­‐integration-­‐test</phase>                        <configuration>                            <check>                                <classRate>95</classRate>                                <instructionRate>95</instructionRate>                                <methodRate>90</methodRate>                                <branchRate>95</branchRate>                                <complexityRate>95</complexityRate>                                <lineRate>95</lineRate>                            </check>                        </configuration>                    </execution>
  • 46.
    Run code coveragewith the integration tests Integration tests/test compile test-compile mvn install test coverage package integration-test verify Uninstrumented JAR Coverage checks and report
  • 47.
    Minimal overhead Build Time Normal build With JaCoCo
  • 48.
    Reuse binaries whereverpossible Default build 1.0.203 Deploy to TEST Acceptance Tests 1.0.201 1.0.202 1.0.203 Deploy to UAT
  • 49.
    Have a separateacceptance test suite Acceptance Tests TEST UAT PROD
  • 50.
    Take code qualityseriously Checkstyle Findbugs
  • 51.
    Take code qualityseriously Code quality metrics mvn site
  • 52.
    Take code qualityseriously Pick and choose your metrics Code quality metrics mvn pmd:check mvn findbugs:check mvn checkstye:checkstyle Fail the build if there are violations
  • 53.
    Avoid the MavenRelease Plugin Don’t sweat the version numbers
  • 54.
    Developers always workon a SNAPSHOT version 1.0-SNAPSHOT This number is pretty arbitrary
  • 55.
    Jenkins sets arelease candidate version at the start of the build pipeline 1.0-SNAPSHOT 1.0.203 This number is a build counter
  • 56.
    This version goesthrough the build pipeline 1.0.203 Unit tests Acceptance tests Code quality metrics Deploy to TEST
  • 57.
    This version goesthrough the build pipeline 1.0.203 1.0.204 1.0.205 Unit tests Acceptance tests Code quality metrics Deploy to TEST Acceptance Tests 1.0.203 1.0.204 1.0.205
  • 58.
    Create a newrelease branch Update the version number Build and test release candidate Did it work? No Yes Drop release branch Push release branch Notify everyone Deploy release candidate
  • 59.
    Create a newrelease branch Update the version number Build and test release candidate 1.0.203 Did it work? No Yes Drop release branch Push release branch Notify everyone Deploy release candidate
  • 60.
    Create a newrelease branch Update the version number Versions Plugin Build and test release candidate mvn versions:set -DnewVersion=1.0.203 Did it work? No Yes Drop release branch Push release branch Notify everyone Deploy release candidate
  • 61.
    Create a newrelease branch Update the version number Build and test release candidate Did mvn verify ... it work? No Yes Drop release branch Push release branch Notify everyone Deploy release candidate
  • 62.
    And make itvisible The Build Pipeline plugin
  • 63.
    Let’s see itin action! TEST UAT PROD Jenkins
  • 64.
    Let’s see itin action!
  • 65.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 66.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 67.
    initial-build Links to binary artifacts in Artifactory Release candidate number
  • 68.
    initial-build Links to binaryartifacts in Artifactory
  • 69.
    initial-build Use a parameterized build to configure the major build version Users can override the default major version
  • 70.
    initial-build Create a new branch Update the version in the pom files Build the binaries
  • 71.
    initial-build Conditional build step plugin If the build succeeds... Commit the changes and push the branch to the repository
  • 72.
    initial-build If the build fails... Delete the branch
  • 73.
    initial-build Deploy the releasecandidate to Artifactory
  • 74.
    initial-build Deploy to the test environment Target platform
  • 75.
    initial-build <plugin> <groupId>com.jelastic</groupId> <artifactId>jelastic-maven-plugin</artifactId> <version>1.6</version> <configuration> <email>${jelastic.username}</email> <password>${jelastic.password}</password> <context>${jelastic.context}</context> <environment>${jelastic.environment}</environment> <api_hoster>app.jelastic.servint.net</api_hoster> </configuration> </plugin>
  • 76.
    initial-build Archive binary Update the build description
  • 77.
    initial-build Archive binary Pass the release branch to the next build job
  • 78.
    initial-build Don’t start anew build pipeline if one is currently running.
  • 79.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 80.
    initial-build code-quality Pass in the release we want to build against deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 81.
    initial-build code-quality deploy-to-test Build from the release candidate branch acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 82.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 83.
    initial-build code-quality Copy the WAR file from the initial build deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 84.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat ...deploy this WAR file acceptance-tests deploy-to-prod
  • 85.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod the acceptance tests ...and run
  • 86.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat What platform do we run the acceptance test against acceptance-tests deploy-to-prod
  • 87.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat What platform do we run the acceptance test against acceptance-tests deploy-to-prod
  • 88.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 89.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat What platform do we run the acceptance test against acceptance-tests deploy-to-prod
  • 90.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat What platform do we run the acceptance test against acceptance-tests deploy-to-prod
  • 91.
    initial-build code-quality deploy-to-test acceptance-tests deploy-to-uat Build promotion status acceptance-tests deploy-to-prod
  • 92.
    initial-build Copy the WARfile from the initial build... code-quality deploy-to-test acceptance-tests deploy-to-uat ...and deploy it to UAT acceptance-tests deploy-to-prod
  • 93.
    A build promotioninitial-builddeploy to production process to code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 94.
    A build promotioninitial-builddeploy to production process to code-quality deploy-to-test acceptance-tests deploy-to-uat acceptance-tests deploy-to-prod
  • 95.
    Build pipeline foran overview of the process
  • 96.
    Thank You John  Ferguson  Smart Email:  john.smart@wakaleo.com Web:  hHp://www.wakaleo.com TwiHer:  wakaleo