Build Configurations: The EasyAnt Way |
|
| Monday, 29 June 2009 10:53 |
Build ConfigurationsLet us consider a few scenarios which make necessity for build configurations obvious. Scenario I: Your build is a web application. You need a quick jetty-deploy available for convenient development. Conversely, you need a javadocs plugin in your release builds but, don't want them to interfere with your development environment. Scenario II: You need your build to shape up differently for Linux and Windows runtimes. Maybe, you want your Windows build to package a DLL or CAB file additionally. Build configurations are a means provided to the authors of an EasyAnt build to create common usage-patterns and publish them through the familiar module.ivy. A user can then request a profile through a CLI. Instead of being ultra-flexible in its outlook, EasyAnt still allows common and valuable patterns to be accommodated in the same build. Configuration Scope All build configurations in EasyAnt are scoped at the level of a project. However, the mechanism of specifying the configuration allows you configure along multiple aspects. For example, along use-cases (dev/production/test), along target platforms (windows/linux), etc. What aspects can one configure? You can associate the following things with a particular build configuration: (a) Property values (b) Dependencies (c) Plugins For example, you are allowed to specify property x is available for only configuration ‘conf1' and not rest. Similarly, you may specify use the ‘javadocs' plugin only for ‘release' configuration, and not ‘dev' configuration. And, this module depends on dependency d only for configuration ‘windows'. Declaring Build Configurations Configurations are entirely defined inside the familiar module.ivy specification. EasyAnt attempts to reuse and extend the meaning of the A typical conf tag can be converted into a profile declaration if it contains ea:type="profile" attribute. This is an instruction to EasyAnt to treat this as a Profile/Configuration. The above statement declares a new build configuration called myconf, Attaching build elements to a configuration Now that we have declared a build configuration, how do we define it? A build configuration is defined by attaching properties, plugins and dependencies to it. Here is how you may attach properties to particular configurations: <ea:build type="org.apache.easyant.buildtypes#build-std-java;0.2"> <ea:property name="foo" value="bar" conf="windows"/> <ea:property name="foo" value="foobar" conf="linux"/> <ea:property name="goo" value="bar" conf="windows, linux"/> <ea:plugin module="myplugin" conf="windows"/> </ea:build> As is self-evident, the property foo will assume different values for ‘windows' and ‘linux' configurations. On the otherhand, declaration of ‘goo' attaches itself to both windows and linux profiles with the same value. Similarly, the plugin myplugin gets attached to the ‘windows' configuration only but, is not available in the linux configuration. Activating a Configuration Build configurations in EasyAnt are activated through Command Line in two ways: easyant -buildconf myconfiguration easyant -C myconfiguration Any of the above commands would trigger the build process using myconfiguration build configuration. A Practical Use Case This section tries to illustrate the technical details of Build Configurations. We will try to setup a web application build and then configure it for three different target environments, viz. Release, Testing and Development. Of these, release and testing configurations require to publish coverage reports. The development configuration focuses on making developers life easy. So, it needs a quick jetty deploy functionality available in the build. Let us try to set up a simply EasyAnt build with the above intention in mind. <conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf"/> <conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases."/> <conf name="release" visibility="public" ea:type="profile" description="Declares a build configuration for release builds"/> <conf name="testing" visibility="public" ea:type="profile" description="Declares a build configuration for testing builds"/> <conf name="dev" visibility="public" ea:type="profile" description="Declares a build configuration for dev builds"/> </configurations> The above module.ivy snippet declares the three build configurations, viz. ‘release', ‘testing' and ‘dev'. Now, we need to attach our requirement dependencies to each of these configurations. So, we modify our <ea:property name="test.framework" value="testng"/> <ea:property name="run.main.classname" value="org.apache.easyant.example.Example" conf="dev"/> <ea:plugin module="org.apache.easyant.plugins#jetty-deploy;0.1" as="jetty" conf="dev"/> <ea:plugin module="org.apache.easyant.plugins#run-java;0.1" as="run-java" conf="dev"/> <ea:plugin module="org.apache.easyant.plugins#emma;0.1" as="emma" conf="release,testing"/> </ea:build> In the above snippet, jetty-deploy, run-java and emma plugins have been declared and attached to different build configurations. While jetty-deploy and run-java plugins have been attached to dev configuration, the emma plugin has been attached to both testing and release configurations. The jetty-deploy plugin allows a quick deployment of the webapp build on a jetty server. The run-java plugin allows you to execute any java class. Let us assume our dev environment requires us to execute a java class. So we include this dependency to our dev environment. Further, the run-java plugin requires the class name to be executed through the property run.main.classname. So, we additionally define this property and attach it to the dev configuration as well. On the other hand, for our release builds, generation of coverage reports is a process requirement. And in testing, coverage reports are an obvious requirement. So we attach the emma plugin to both these configurations. So, this is how our final module.ivy looks: xmlns:ea="http://www.easyant.org"> <info organisation="org.apache.easyant" module="webapp-java" status="integration"> <description> This project is a sample of a java webapplication making use of build configurations </description> <ea:build type="org.apache.easyant.buildtypes#build-webapp-java;0.1"> <ea:property name="test.framework" value="testng" /> <ea:property name="run.main.classname" value="org.apache.easyant.example.Example" conf="dev" /> <ea:plugin module="org.apache.easyant.plugins#jetty-deploy;0.1" as="jetty" conf="dev" /> <ea:plugin module="org.apache.easyant.plugins#run-java;0.1" as="run-java" conf="dev" /> <ea:plugin module="org.apache.easyant.plugins#emma;0.1" as="emma" conf="release,testing" /> </ea:build> </info> <configurations> <conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" /> <conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases." /> <conf name="release" visibility="public" ea:type="profile" description="Declares a build configuration for official builds" /> <conf name="testing" visibility="public" ea:type="profile" description="Declares a build configuration for testing builds" /> <conf name="dev" visibility="public" ea:type="profile" description="Declares a build configuration for dev builds" /> </configurations> <publications> <artifact type="war" /> <artifact e:classifier="source" /> </publications> <dependencies> <dependency org="org.testng" name="testng" rev="5.7" conf="test->master"> <artifact name="testng" type="jar" e:classifier="jdk15" /> </dependency> </dependencies> </ivy-module> Running different configurations/profiles With the above module.ivy, you can go ahead and run the build against any of the configuration. For example, if you are a developer, trying to deploy and test your changes on jetty, you would like to run: easyant -C dev jetty:run easyant -C dev run-java:run The first command will build and package your app, and deploy it on a jetty instance. The second will run the ${run.main.classname} class in a new JVM. Or, try out this - easyant -C testing emma:emma easyant -C release emma:emma This would generate a emma coverage report for your project. Conclusion In this article, we discussed how build profiles or configurations are handled in EasyAnt. What elements/customizations constitute a configuration are also discussed. Subsequently, an example module.ivy was described to showhow configurations could be created and used in different environments. Please feel free to share any ideas or feedback with easyant@googlegroups.com . You can visit http://www.easyant.org/doc/ for more information on EasyAnt. Siddhartha Purkayastha is a Technical Lead with Arcot R&D Software. He is also a Committer member for the EasyAnt project (http://www.easyant.org ). Before joining Arcot, he was a Technical Associate with Trilogy Software. His areas of interest include Build automation and process improvement (using established standards and frameworks), and Application Development (architecture, design and development). He can be reached at kpsiddharth@gmail.com . Jean Louis Boudart is an independent consultant focused on Java/JEE technologies. Deep involvement in open source community (Project lead on EasyAnt project : http://www.easyant.org, Hudson commiter ). He is particularly interested in subjects related to software quality improvement (build automation, dependency management, continuous integration, quality audit, ...). He can be reached at jeanlouis.boudart@gmail.com .
Set as favorite
Bookmark
Email this
Hits: 1671 Trackback(0)Comments (0)
|
| Last Updated on Tuesday, 21 July 2009 14:55 |


Build Configurations
