Monday, June 25, 2007

ANT as a automation tool

When it come to build automations, ANT is one of the most powerful tool that can be used. There might be other tools too, but ANT is most widely available and usable. If you are new to ANT then visit http://ant.apache.org. If you want to explore the power of ANT then visit http://ant.apache.org/manual/index.html.
To write or use ANT first you will have to install it. To find out from where to download and how to isntall ANT please visit http://ant.apache.org/manual/install.html.

Here I will take an process as an example and we'll see how we can automate the process using ANT and make our life easier.

Consider the following process:
You have some bunch of programmers working on a project and you are using a central repository; CVS or VSS. At the end of the day when all the programmers are done with their devlopment/bug fixing task for the day a monotonous process is required to be followed. All the source code from the repository needs to be taken and sent to your team at other end (Onsite) through ftp. This process can be broken down in to following steps:
1. Get the latest source code from the repository.
2. Label the source code appropriately to indicate today's work.
3. Filter the files that need to be send.
4. Archive your source code to zip or gzip.
5. Upload the zip file to ftp.
6. And finally send a mail to all the stakeholders stating the upload path and a release note.

Now if we perform this process manually, it will take considerable time and might also cause problems due to human errors.
But if we automate this process, believe me it will not take more than 30 secs to release a project with around 500 source files. What we need to do is identify the atomic tasks to be performed and automate them.

As you can see, the steps mentioned above are atomic tasks that needs to be performed. ANT provides a huge set of core as well as optional tasks [].
I hope that you have basic knowledge about targets, tasks, taskdef etc.

We will define each step or set of steps as a target. Though the complete script can be writting in one target, I prefer it former way for obvious reasons.

The paramters specified in the code snippets are explained in the end.
Considering the above process;

1. Get the latest source code from the repository.
If you are using CVS, ANT provides core task to perform CVS operations.
This can be written in ANT as:

<cvspass cvsRoot="${cvs.root}" password="${cvs.pass}" passfile=".cvs-pass"/>
<cvs command="login" cvsRoot="${cvs.root}" passfile=".cvs-pass"/>
<cvs dest="${base.dir}" cvsRoot="${cvs.root}" command="update -A -dPC" passfile=".cvspass"/>

If you are using VSS, ANT provides optional task for the same.
<vssget serverpath="${vss.server}" vsspath="${vss.path}/${app.name}" ssdir="${vss.ssdir}" localpath="${base.dir}" login="${vss.username},${vss.pass}" recursive="true" />
The piece of code above will get the latest version of code from repository into the specified destination folder.

2. Label the source code appropriately to indicate released work.

<echo message="Tag ${vss.path}/${app.name} with ${app.name}-${timestamp}"/>
<cvs cvsRoot="${cvs.root}" command="tag ${app.name}-${timestamp}" package="${app.name}" passfile=".cvspass"/>

If you are using VSS, ANT provides optional task for the same.
<echo message="Label ${vss.path}/${app.name} with ${app.name}-${timestamp}"/>
<vsslabel serverpath="${vss.server}" vsspath="${vss.path}/${app.name}" ssdir="${vss.ssdir}" login="${vss.username},${vss.pass}" label="${app.name}-${timestamp}" />

The above two tasks can be specified in one target for modularity and hence the reaulting target will be:

<!-- CVS task Starts-->
<target name="cvs" description="get the latest source code from CVS" >
<cvspass cvsRoot="${cvs.root}" password="${cvs.pass}" passfile=".cvs-pass"/>
<cvs command="login" cvsRoot="${cvs.root}" passfile=".cvs-pass"/>
<cvs dest="${base.dir}" cvsRoot="${cvs.root}" command="update -A -dPC" passfile=".cvspass"/>
<cvs cvsRoot="${cvs.root}" command="tag ${app.name}-${timestamp}" package="${app.name}" passfile=".cvspass"/>
</target>
<!-- CVS task ends -->

<!-- VSS task starts -->
<target name="vss" description="get the latest source code from VSS" >
<vssget serverpath="${vss.server}" vsspath="${vss.path}/${app.name}" ssdir="${vss.ssdir}" localpath="${base.dir}" login="${vss.username},${vss.pass}" recursive="true" />
<echo message="Label ${vss.path}/${app.name} with ${app.name}-${timestamp}"/>
<vsslabel serverpath="${vss.server}" vsspath="${vss.path}/${app.name}" ssdir="${vss.ssdir}" login="${vss.username},${vss.pass}" label="${app.name}-${timestamp}" />
</target>
<!-- VSS task ends -->

Now moving to next steps:
3. Filter the files that need to be send.
4. Archive your source code to zip or gzip.
These two steps include filtering out those files which need to be sent and bundle those files.
The target to accomplish this task would look something like this:

<target name="package" description="Package the source code and Contextroot" >
<property name="target.filename" value="${app.name}-${timestamp}.zip"/>
<zip zipfile="${zip.dir}/${app.name}/${target.filename}" >
<fileset dir="${base.dir}">
<include name="src/**"/>
<include name="ContextRoot/jsp/**"/>
<include name="ContextRoot/WEB-INF/**"/>
<include name="src/META_INF/ejb-jar.xml"/>
<exclude name="ContextRoot/WEB-INF/classes/**"/>
<exclude name="ContextRoot/WEB-INF/lib/**"/>
<exclude name="ContextRoot/jsp/**/*.gif"/>
<exclude name="ContextRoot/jsp/image/**"/>
<exclude name="src/META_INF/**"/>
</fileset>
</zip>
</target>

We have used here ANT task to zip a set of files. The set of files can be specified
Here you need to specify the parameters like the target path and name of the zip file, the source files to be zipped, etc.

5. Upload the zip file to ftp server.
ANT provides a task that allows you to upload files to ftp server. The ANT target for the same is:

<target name="upload" description="uploads to FTP">
<echo message="Uploading file to ftp : ${target.filename}"/>
<ftp server="${ftp.url}" userid="${ftp.username}" password="${ftp.password}" binary="yes" remotedir="${ftp.remotedir}">
<fileset dir="${zip.dir}/${app.name}">
<include name="${target.filename}"/>
</fileset>
</ftp>
<echo message="Release uploaded successfully "/>
</target>

As you can see, the parameters that needs to be provided are connection details for ftp server, transfer mode, files upload path and source file.

The next and final step:
6. And finally send a mail to all the stakeholders stating the upload path and a release note.
ANT provides a optional task for sending MIME mail. But this task highly depends on what contents you require in your mail.
For this task, I have written a class that generates a release note for me which I attach to my mail. Though this highly depends on your requirement but here I have used a very important feature of ANT that is developing custom tasks.
To know how to develop a custoom task, please visit ant.apache.org/manual/develop.html
Here taskdef is used to declare a new Task to ANT and which class should be loaded to implement this task.
The below code declares a new task which is named as releasenote and then this task is to create the release note.

<taskdef name="releasenote" classname="com.note.ReleaseNoteCreator"/>
<releasenote appName="${app.name}" noteName="${note.name}" releasedFile="ftp://ftp.zensar.com/${ftp.remotedir}/${target.filename}"/>

Once the release note is created, the following task will release a mail for you according to the paramters provided.

<mail from="${mail.from}" tolist="${mail.to}" cclist="${mail.cc}" files="${note.name}" user="${mail.user}" password="${mail.pass}" ssl="no" replyto="${mail.reply}" subject="${mail.subject}" mailhost="${mail.host}" mailport="${mail.port}" messagefile="${mail.message}"/> <!--message="${mail.message}"/-->

The complete target will look something like this:

<target name="mail" description="Send release mail" depends="init">
<echo message="Generating Release Note"/>
<property name="note.name" value="${zip.dir}/${app.name}/ReleaseNote-${timestamp}.txt"/>
<mail from="${mail.from}" tolist="${mail.to}" cclist="${mail.cc}" files="${note.name}" user="${mail.user}" password="${mail.pass}" ssl="no" replyto="${mail.reply}" subject="${mail.subject}" mailhost="${mail.host}" mailport="${mail.port}" messagefile="${mail.message}"/> <!--message="${mail.message}"/-->
</target>

As you can see each target depends on a "init" target. This "init" target is used to perform some chores before starting the reelase process. Here it defines a timestamp variable which is used to generate distinct filesnames. The init target will look something like this
Here the record task is used for ANT logging.

<target name="init" description="Create password file and try Login">
<tstamp/>
<property name="timestamp" value="${DSTAMP}-${TSTAMP}"/>
<record name="${log.file}-${timestamp}.log" action="start" append="yes" loglevel="debug"/>
<echo message="Update, Tag, Package, Upload, and release latest source code from ${rep.type} for ${app.name}"/>
</target>

And finally you can either define a target which will call other targets or set the target execution sequence while executing ANT build file.

My final ANT build file for this process comes out to be:

<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="RELEASE_BUILD" default="getsource" basedir=".">

<property file="${arg-app}-build.properties"/>
<property name="rep.type" value="${arg-rep}"/>
<property name="base.dir" value="${ws.dir}/${app.name}"/>

<taskdef name="releasenote" classname="com.note.CreateReleaseNote"/>
<target name="init" description="Create password file and try Login">
<tstamp/>
<property name="timestamp" value="${DSTAMP}-${TSTAMP}"/>
<record name="${log.file}-${timestamp}.log" action="start" append="yes" loglevel="debug"/>
<echo message="Update, Tag, Package, Upload, and release latest source code from ${rep.type} for ${app.name}"/>
</target>

<!-- CVS Starts-->
<target name="cvs" description="get the latest source code from CVS" >
<cvspass cvsRoot="${cvs.root}" password="${cvs.pass}" passfile=".cvs-pass"/>
<cvs command="login" cvsRoot="${cvs.root}" passfile=".cvs-pass"/>
<cvs dest="${base.dir}" cvsRoot="${cvs.root}" command="update -A -dPC" passfile=".cvspass"/>
<cvs cvsRoot="${cvs.root}" command="tag ${app.name}-${timestamp}" package="${app.name}" passfile=".cvspass"/>
</target>
<!-- CVS ends -->

<!-- VSS starts -->
<target name="vss" description="get the latest source code from VSS" >
<vssget serverpath="${vss.server}" vsspath="${vss.path}/${app.name}" ssdir="${vss.ssdir}" localpath="${base.dir}" login="${vss.username},${vss.pass}" recursive="true" />
<echo message="Label ${vss.path}/${app.name} with ${app.name}-${timestamp}"/>
<vsslabel serverpath="${vss.server}" vsspath="${vss.path}/${app.name}" ssdir="${vss.ssdir}" login="${vss.username},${vss.pass}" label="${app.name}-${timestamp}" />
</target>
<!-- VSS ends -->

<!-- Common Packaging, uploading and mail starts -->
<taskdef name="releasenote" classname="com.note.CreateReleaseNote"/>

<target name="package" description="Package the source code and Contextroot" >
<property name="target.filename" value="${app.name}-${timestamp}.zip"/>
<zip zipfile="${zip.dir}/${app.name}/${target.filename}" >
<fileset dir="${base.dir}">
<include name="src/**"/>
<include name="ContextRoot/jsp/**"/>
<include name="ContextRoot/WEB-INF/**"/>
<include name="src/META_INF/ejb-jar.xml"/>
<exclude name="ContextRoot/WEB-INF/classes/**"/>
<exclude name="ContextRoot/WEB-INF/lib/**"/>
<exclude name="ContextRoot/jsp/**/*.gif"/>
<exclude name="ContextRoot/jsp/image/**"/>
<exclude name="src/META_INF/**"/>
</fileset>
</zip>
</target>

<target name="upload" description="uploads to FTP">
<echo message="Uploading file to ftp : ${target.filename}"/>
<ftp server="${ftp.url}" userid="${ftp.username}" password="${ftp.password}" binary="yes" remotedir="${ftp.remotedir}">
<fileset dir="${zip.dir}/${app.name}">
<include name="${target.filename}"/>
</fileset>
</ftp>
<echo message=" Release uploaded successfully "/>
</target>

<target name="mail" description="Send release mail" depends="init">
<echo message="Generating Release Note"/>
<property name="note.name" value="${zip.dir}/${app.name}/ReleaseNote-${timestamp}.txt"/>
<releasenote appName="${app.name}" noteName="${note.name}" releasedFile="ftp://ftp.zensar.com/${ftp.remotedir}/${target.filename}"/>
<mail from="${mail.from}" tolist="${mail.to}" cclist="${mail.cc}" files="${note.name}" user="${mail.user}" password="${mail.pass}" ssl="no" replyto="${mail.reply}" subject="${mail.subject}" mailhost="${mail.host}" mailport="${mail.port}" messagefile="${mail.message}"/> <!--message="${mail.message}"/-->
</target>

<!-- Common Packaging, uploading and mail ends -->
<target name="getsource" description="Update, Tag, Package, Upload, and release latest source code from repository" depends="init">
<antcall target="${rep.type}" />
<echo message="Update Latest Source code completed"/>
<antcall target="release" />
</target>

<target name="release" description="Package, Upload, and release Mail" depends="package,upload,mail">
<echo message="**Release of ${app.name} latest source code completed successfully**"/>
</target>

</project>

And the properties file that specifies all the paramters required is...

# Application Name as used in APWORKS.
app=MyProject
app.name=MyProject


###### CVS Path (Optional) ########
cvs.root=:pserver:husain@192.168.1.155:/app/cvs/cvsroot
#CVS Password
cvs.pass=

# The cvs module path of the application required for checkout operation.
cvs.module=DEVELOPMENT/MyProject
######## VSS Details #########
# As specified in VSS server path
vss.server=\\\\servername\\repository\\
vss.path=$/VSS/DEVELOPMENT
vss.ssdir=D:/VSS Client
vss.username=vssuser
vss.pass=vssuserpass

####### Workspace Details ##########
#Workspace location. The code from CVS is updated at ws.dir/app.name
ws.dir=D:/ide/workspace
#Target local as well as backup Directory to store zip files to be uploaded to ftp server. Used as parent dir to app.name dir.
zip.dir=D:/BackUp


######## ftp Details ########
ftp.url=ftp.ind.zensar.com
#Target ftp directory
ftp.remotedir=SOURCE/MyProject
ftp.username=user
#ftp password.
ftp.password=password

##############Mail Settings. Used to mail the release note.
mail.message=mailBody.txt
mail.host=mail.mailserver.com
mail.port=25
# list of mail ids
mail.to=target1@domain.com,cm@domain.com
mail.cc=target3@domain.com,cm2@domain.com

#Senders mail-id
mail.user=myself@domain.com
mail.from=myreplymail@domain.com

#Reply mail-id
mail.reply=myreplymail@domain.com
#Senders mail-id password.
mail.pass=mypassword
mail.subject=Source Code Release [Auto-Generated]

#Logger
log.file=D:/BackUp/buildlog


Resources:
Ant Home Page: http://ant.apache.org
Ant installation Manual: http://ant.apache.org/manual/install.html
Ant Manual: http://ant.apache.org/manual/index.html
A good article on ANT Automation: http://www.onjava.com/pub/a/onjava/2002/07/24/antauto.html

18 comments:

  1. Good article husain.

    well i found good link on "Project Dependencies Using Ant" : http://www.exubero.com/ant/dependencies.html

    might be useful.

    By the way thanks for the info.

    ReplyDelete
  2. Nice article, thanks for sharing this

    ReplyDelete
  3. nice article about Ant. did u ever use netbeans with Ant, i think ant is already integrated with netbeans. but we can still customize it.

    anyways good work.

    ReplyDelete
  4. helped me alot, thanks!

    ReplyDelete
  5. After you got the orthodox amount of wealth of currency,
    you have failing wealth problems. payday loansThis short loan is well thought out to be the best business enterprise derivative
    of speedy currency by applying with this loan. Once you have nonheritable inst
    pecuniary resource up to $1500 bucks, grade since this effectuation that they
    cannot get loans well. Lenders are providing you cash even later
    cash would be in your relationship. Under this situation, total household is
    affected as pecuniary resource go out your elect lenders.
    Speedy day loans are authorised for the same day fast loans are best activity for you.
    As the name refers, these loans do get to prize a
    defrayal agenda that fits your of necessity as well as your monetary fund.
    Whenever exploitation the idealistic loan troupe you strength be jolly complacent big
    difficulty the group action group as of late. Is it departure
    to be used when you look at deep, it saves your medium of exchange.

    ReplyDelete
  6. Before, you pick out a investor for your cash advance,
    make theproblem is play indispensable role that why they
    can't able to snub it. Nowadays, attractive loan is not a big deal since different online lenders 18 old age of age. This wealth is a shortened term cash help and will refund what you owe and to do this, they oft postulate you indirect. pay day loansBenefits of a security interest For most of the gain in home and the loan amount of money gets canonical speedily inside a day.

    ReplyDelete
  7. While applying with this loan, you do not lenders in the UK loan marketplace.
    payday loansAmongst the respective attributes,
    the most important characteristic for you to utilise these loans is that you as you can easy get this done a car loan which you can then
    refund tardily. But aft the due date the receiver will have conventional loans
    that cannot fund as apace.

    ReplyDelete
  8. How long will it take is improved for you to helpfulness same day Loans Australia helpable online.
    The Loan is acknowledged to you without lead us to respective big or lilliputian problems.
    Here providers of loan are very professionals and move by the ambulant sound users.
    3 month payday loansBreak this blue-chip quantity shortly thus it would unquestionably take increase for your the action of a famous and supposed causal agency with high care.
    And you can easy have the location is some pinch and you are already
    out of cash. Sometimes the time that taken may be so less and depending on the amount of
    money of the out for all their problems.

    ReplyDelete
  9. That's what I was meaning.... You'd haνe to bе blіnd
    tο thіnk ԁifferent.

    my blog ... unsecured long term loans

    ReplyDelete
  10. The qualification availed chop-chop to solution an imperative financial need.
    You just need to go online to roll up the cash
    in hand necessary at a very truncated observance.
    pay day loansThe recipient would get an contiguous approval, as these are perfect business enterprise help.

    They render you bother free easy commercial enterprise without speech act you
    fee, therefore your curiosity is safeguarded to a large
    stage. At present only the enduring citizens of to give monetary system borrowers a more light
    defrayal alternative.

    ReplyDelete
  11. Ϲοuld do with ѕome extra stuff on thіs - аny opiniοns coѵеring
    anуthing I could read or what ωebsitеs
    I might go to??

    Hаve a look at my blog post - best tenant loans

    ReplyDelete
  12. Not ѕure whether tо buy a book on this mysеlf, or
    just read рlenty of webѕites. Can there be that much to it?


    Heгe іs my web-site :: cheap Personal loans

    ReplyDelete
  13. I mіght get аround tо this myѕelf
    somеtime, іf I can get fundіng.


    mу web рage - small personal loans

    ReplyDelete
  14. So - Untitlеd - I would never have thought it ωould
    be so gοod a read as it has been. Now I shoulԁ actuаllу go and do
    some worκ!

    Mу web blоg Unsecured personal loans

    ReplyDelete
  15. It's awesome to visit this web site and reading the views of all mates concerning this post, while I am also keen of getting knowledge.

    Here is my homepage; best reviews

    ReplyDelete
  16. I'm really enjoying the theme/design of your blog. Do you ever run into any web browser compatibility issues? A handful of my blog readers have complained about my blog not operating correctly in Explorer but looks great in Chrome. Do you have any suggestions to help fix this problem?

    my web-site; best reviews

    ReplyDelete
  17. Not all activities need to be competitive instead, you might play a some of the impressive constituents which can
    assist the body to lose fat. Phen375 is usually a powerful robust, rapid weight loss supplement within the product, used daily by
    way of liquid component of the drug, used as L-carnation. There
    are some products during the market which will aid you melt off as an appetite suppressant and fat burner.
    phen375For those times you get hold of Phen375 is normally
    horrible of your tremendous to a new job. Chances are youll even see
    your current how do people acquire more Phen375 critiques,
    which supports help you to lose weight naturally within the correct way.

    The initial products formulated with Phentermine has been frozen although phen375 fat
    burnercomprises everything to help one drop will
    maintain your fat burning capacity up, this will happen to you, certain.
    The particular opinions made for Phen375 likewise have cherished discovering media discovered extra details about
    these body fat burner.

    ReplyDelete