Sunday, January 22, 2017

Maven - Build Automation

Build Automation defines the scenario where dependent project(s) build process gets started once the project build is successfully completed,in order to ensure that dependent project(s) is/are stable.

Example

Consider a team is developing a project bus_core_api on which two other projects app_web_ui and app_desktop_ui are dependent. bus_core_api project is present in C:\ > MVN directory and app_web_ui and app_desktop_ui are present in C:\ > MVN > projects directory
app_web_ui project is using 1.0-SNAPSHOT of bus_core_api project
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>app_web_ui</groupId>
   <artifactId>app_web_ui</artifactId>
   <version>1.0</version>
   <packaging>jar</packaging>
   <name>app_web_ui</name>
   <url>http://maven.apache.org</url>
   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>
   <dependency>
         <groupId>bus_core_api</groupId>
         <artifactId>bus_core_api</artifactId>
         <version>1.0-SNAPSHOT</version>
   <scope>system</scope>
   <systemPath>C:\MVN\bus_core_api\target\bus_core_api-1.0-SNAPSHOT.jar</systemPath>
      </dependency>
   </dependencies>
</project>
app_desktop_ui project is using 1.0-SNAPSHOT of bus_core_api project
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>app_desktop_ui</groupId>
   <artifactId>app_desktop_ui</artifactId>
   <version>1.0</version>
   <packaging>jar</packaging>
   <name>app_desktop_ui</name>
   <url>http://maven.apache.org</url>
   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>
   <dependency>
         <groupId>bus_core_api</groupId>
         <artifactId>bus_core_api</artifactId>
         <version>1.0-SNAPSHOT</version>
   <scope>system</scope>
   <systemPath>C:\MVN\bus_core_api\target\bus_core_api-1.0-SNAPSHOT.jar</systemPath>
      </dependency>
   </dependencies>
</project>
bus_core_api project
<project xmlns="http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>bus_core_api</groupId>
   <artifactId>bus_core_api</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>   
</project>
Now teams of app_web_ui and app_desktop_ui projects require that their build process should kick off whenever bus_core_api project changes.
Using snapshot ensures that the latest bus_core_api project should be used but to meet above requirement we need to do something extra.
We've two ways
  • Add a post-build goal in bus_core_api pom to kick-off app_web_ui and app_desktop_ui builds.
  • Use a Continuous Integration (CI) Server like Hudson to manage build automation automatically.

Using Maven

Update bus_core_api project pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>bus_core_api</groupId>
   <artifactId>bus_core_api</artifactId>
   <packaging>jar</packaging>
   <version>1.0-SNAPSHOT</version>
   <build>
      <plugins>
         <plugin>            
            <artifactId>maven-invoker-plugin</artifactId>
            <version>2.0.0</version>
            <configuration>
               <debug>true</debug>  
      <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>      
            <projectsDirectory>C:/MVN/projects</projectsDirectory>      
            </configuration>   
            <executions>
               <execution>
                  <id>integration-test</id>
                  <goals>
                     <goal>run</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>     
   </dependencies>
</project>
Let's open command console, go the C:\ > MVN > bus_core_api directory and execute the following mvn command.
C:\MVN\bus_core_api>mvn verify
Maven will start building the project bus_core_api.
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building bus_core_api 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ bus_core_api ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\MVN\bus_core_api\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ bus_core_api ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ bus_core_api ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\MVN\bus_core_api\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ bus_core_api ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ bus_core_api ---
[INFO] Surefire report directory: C:\MVN\bus_core_api\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running bus_core_api.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.047 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ bus_core_api ---
[INFO]
[INFO] --- maven-invoker-plugin:2.0.0:run (integration-test) @ bus_core_api ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Building: app_desktop_ui\pom.xml
[INFO] ..SUCCESS (10.7 s)
[INFO] Building: app_web_ui\pom.xml
[INFO] ..SUCCESS (11.5 s)
[INFO] Building: bus_core_api\pom.xml
[INFO] ..SUCCESS (12.8 s)
[INFO] -------------------------------------------------
[INFO] Build Summary:
[INFO]   Passed: 3, Failed: 0, Errors: 0, Skipped: 0
[INFO] -------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 42.421 s
[INFO] Finished at: 2015-09-27T17:41:42+05:30
[INFO] Final Memory: 12M/247M
[INFO] ------------------------------------------------------------------------

Using Continuous Integration Service with Maven

Using a CI Server is more preferable as developers are not required to updated bus_core_api project pom everytime a new project, for example app-mobile-ui is added as dependent project on bus_core_api project. Hudson automatically manages build automation using Maven dependency management.
automated build Hudson considers each project build as job. Once a project code is checked-in to SVN (or any Source Management Tool mapped to Hudson), Hudson starts its build job and once this job get completed, it start other dependent jobs(other dependent projects) automatically.
In above example, when bus-core-ui source code is updated in SVN, Hudson starts its build. Once build is successful. Hudson looks for dependent projects automatically, and starts building app_web_ui and app_desktop_ui projects.

No comments:

Post a Comment