How to detect the windows OS in ANT - windows

I'm using ant to compile a Java application. The problem is some of the devs are on win 7 and others are on xp and vista. Part of the compiling is to build an msi using WIX, on win7 this is one directory and on xp and vista it's in another.
The ant task is controlled in Maven. I'm after a way of telling the difference between windows os's in ant with a conditional tag to set the wix directory. Any ideas?
I know it will be in this format:
<if>
<condition property="isWin7">
Check for windows 7
</condition>
<then>
set wix path to win 7 installation
</then>
<else>
set to vista/xp wix installation
</else>
</if>
Any help would be great.

It looks like the ANT <condition> can test for name, family & version of operating system:
Ant Tasks - conditions
Based on that link, there are some properties related to OS that we can query. One is the normal family property used in the common code:
<!-- CHECK FOR WINDOWS FAMILY OS -->
<condition property="is_windows">
<os family="windows"/>
</condition>
My version of ANT does not print out a resolved value for ${os.family}.
There is also:
os.name <--- this is the one you need to check
os.arch
os.version
Here's a demo script I made to show the use of these properties:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test" default="build" >
<!-- CHECK FOR WINDOWS FAMILY OS -->
<condition property="is_windows">
<os family="windows"/>
</condition>
<condition property="is_windows_7">
<os name="Windows 7"/>
</condition>
<!-- DISPLAYS WINDOWS OS -->
<target name="display_windows" if="is_windows" >
<echo message="OS Family is: Windows" />
</target>
<target name="build" >
<antcall target="display_windows" />
<echo message="OS Name is: ${os.name}" />
<echo message="OS Architecture is: ${os.arch}" />
<echo message="OS Version is: ${os.version}" />
</target>
</project>
Since answering this question, the code above has been promoted to our production build system, where it is providing shared functionality across Windows & Mac.
#thekbb made a good suggestion to remove the <antcall target="display_windows" />, and update the target definition to depend on display_windows as per the below code:
<target name="build" depends="display_windows">
<echo message="OS Name is: ${os.name}" />
<echo message="OS Architecture is: ${os.arch}" />
<echo message="OS Version is: ${os.version}" />
</target>
This based on the fact that antcall launches a new instance of ant in a new JVM. Some users may find this optimisation easier to understand; others may want to do this for performance reasons.

Related

Selenium running headless Firefox browser in Windows

Is it possible to configure Selenium to use Firefox driver and run the browser headlessly within Windows?
I am aware of other drivers working so within Windows or under Linux but not in the particular case mentioned above. Any reference information (ad-hoc ways to achieve it, limitations, etc.) to read upon is highly appreaciated.
Regards,
It is possible to run browsers (Firefox, IE, ...) via dedicated virtual desktop which supported by OS Windows. One such known helper utility for that task is Headless Selenium for Windows.
Here is the way we are running selenium using firefox driver in headless mode on windows.
Create a windows task schedule, you can either do this using the UI
http://windows.microsoft.com/en-US/windows/schedule-task#1TC=windows-7
or with a command like this :
schtasks /Create /TN Automation /TR C:\automation\automated_regression.bat /SC ONSTART /RU Administrator /RP password /F /V1
in our case, the automation is ant driven, so the automated_regression.bat has something like this
:myLoop
cd c:\automation
call ant_env.bat
call ant -f regression.xml
GOTO myLoop
where the regression.xml has a the typical junit targets of a selenium java project
<property name="main.dir" location="./selweb" />
<property name="src.dir" location="${main.dir}/src" />
<property name="lib.dir" location="${main.dir}/lib" />
<property name="build.dir" location="${main.dir}/build" />
<property name="test.report" location="${main.dir}/testreport">
</property>
<path id="build.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</path>
<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${test.report}" />
</target>
<target name="make dir" depends="clean">
<mkdir dir="${build.dir}" />
<mkdir dir="${test.report}" />
</target>
<target name="compile" depends="clean, make dir">
<javac srcdir="${src.dir}" destdir="${build.dir}" debug="true">
<classpath refid="build.classpath" />
</javac>
</target>
<target name="junit" depends="clean, make dir,compile">
<loadfile property="LATEST" srcFile="LATEST" />
<junit printsummary="no" fork="true" haltonfailure="false" dir="${main.dir}">
<classpath>
<pathelement path="${build.dir}" />
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</classpath>
<formatter type="xml" />
<batchtest todir="${test.report}">
<fileset dir="${build.dir}">
<include name="**/tests/**/*.class" />
</fileset>
</batchtest>
</junit>
<junitreport todir="${test.report}">
<fileset dir="${test.report}">
<include name="**/*.xml"/>
</fileset>
<report format="noframes" todir="${test.report}/html" styledir="${main.dir}/style">
<param name="TITLE" expression="Selenium Test Results for build ${LATEST}"/>
</report>
<report format="frames" todir="${test.report}/html" styledir="${main.dir}/style"/>
</junitreport>
</target>
you can use a logger to record your ant runtime eg.
<record name="log\automation_${timestamp}.log" loglevel="verbose" append="false" />
using this you can follow what is going on in your headless automation.
The ' characters around the executable and arguments are
not part of the command.
[junit] Test com.yourtests ... FAILED
[junit] Implicitly adding C:\automation\dep\apache-ant-1.8.4\lib\ant-launcher.jar;C:\automation\dep\apache-ant-1.8.4\lib\ant.jar;C:\automation\dep\apache-ant-1.8.4\lib\ant-junit.jar;C:\automation\dep\apache-ant-1.8.4\lib\ant-junit4.jar to CLASSPATH
.....
'org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner'
'com.yourtests'
'filtertrace=true'
'haltOnError=false'
'haltOnFailure=false'
'showoutput=false'
'outputtoformatters=true'
'logfailedtests=true'
'logtestlistenerevents=false'
'formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,c:\automation\selweb\testreport\TEST-com.yourtests'
'crashfile=c:\automation\junitvmwatcher2114698975676150832.properties'
'propsfile=c:\automation\junit4190343520192991051.properties'
We have followed this approach and it's working, even screen shots are being taken and inserted in the ant-junit html report.
So the essence is that you need to run your selenium through windows Tasks Scheduler and it will run in headless mode. I think something similar can be done under linux using the cron, but i haven't tried it out to see if it works.

Izpack installer for non-java applications

Can the Izpack installer be used to install a non-java application?
Thanks,
Abdulfattah.
It should be. It will bundle everything together in a jar file. For the pack tag of the install file, call the following:
<pack name="PROJECTPACKNAME" required="yes" preselected="yes"
installGroups="New Application">
<description>PROJECT install</description>
<file src="#{DIRECTORYNAME.dir}" targetdir="$INSTALL_PATH" />
</pack>
For DIRECTORYNAME, you have to declare a property in your build file, ie:
<property name="DIRECTORYNAME.dir" value="/apps/MyProjectName"/>
then have a target in the build file:
<target name="SftWreBundle" depends="init" description="build the software bundle">
<taskdef name="izpack" classpath="${izpack.dir}/lib/standalone-compiler.jar" classname="com.izforge.izpack.ant.IzPackTask" />
<izpack input="install.xml" output="${dist}/${product.short.name}-${product.version}-install.jar"
installerType="standard" inheritAll="true"
basedir="${basedir}" compression="deflate" compressionlevel="9" />
</target>
You may want to clean your working directory before running this target.

is it possible to make nant run a publish on web application project

is it possible to make nant run a publish on mvc project or a good old web application project
and after the publish make nant FTP the files to the web server
UPDATE: found the solution to the ftp problem
Nant ftp task thanks Paco
what i mean by publich
is there a command line application or nant task that can public like visual studio publish...
The visual studio publish command rebuilds your solution and then copies the files in the solution directory to a new directory. I use the following target to do almost the same:
<target name="copyToPublish">
<delete dir="${dir.publish}" />
<mkdir dir="${dir.publish}" />
<mkdir dir="${dir.publish}\wwwroot"/>
<copy todir="${dir.publish}\wwwroot" includeemptydirs="false">
<fileset basedir="${website.dir}">
<exclude name="**/*.cs"/>
<exclude name="**/*.pdb"/>
<exclude name="**/*.csproj*"/>
<exclude name="**/obj/**"/>
<include name="**/*.*"/>
</fileset>
</copy>
<mkdir dir="${dir.publish}\database"/>
<copy todir="${dir.publish}\database" includeemptydirs="false">
<fileset basedir="${dir.databasescripts}">
<include name="**/*.sql" />
</fileset>
</copy>
<xmlpoke
file="${dir.publish}\wwwroot\Web.config"
xpath="/configuration/system.web/compilation/#debug"
value="false" />
<xmlpoke
file="${dir.publish}\wwwroot\Web.config"
xpath="/configuration/system.web/trace/#enabled"
value="false" />
<move file="${dir.publish}\wwwroot\Web.config" tofile="${dir.publish}\wwwroot\Release.config" overwrite="true" />
<delete file="${dir.publish}\wwwroot\Web.config" />
</target>
Before this target you have to run the normal build procedure of course.
There is a Ftp Task for nant.
Beside that, you have to create a script that copies the files and directories you need and the config files. I don't do it automatically, because I want to have control over database update scripts and changes in web.config.

NAnt/NAntContrib 'VB6' failed to start on remote build

Background
I'm putting together a Continuous Integration system at work on two VMs running on my local desktop. VM #1 (Toolbox) is running CruiseControl.Net, Subversion, BugTracker.Net and SQL Server Express. VM #2 (BuildMaster) is running NAnt with NAntContrib and has VB 6.0 and the 1.0/1.1/2.0/3.5 .Net Framework SDKs installed. The intent is to tightly control what's installed on BuildMaster and be much looser on Toolbox and developer workstations.
Issue
I had a CCNet project on Toolbox that successfully compiled a test VB 6.0 application on BuildMaster, but the build started failing last week. The only thing I remember doing was install BugTracker.Net and SQL Server Express on Toolbox.
Symptoms
The build fails and returns an exception:
<![CDATA[Starting 'vb6 ( /make "\\buildmaster\Working\TestApp\TestApp.vbp" /outdir "\\buildmaster\Working\TestApp\build" /out "\\buildmaster\Working\TestApp\TestApp.build.err")' in '\\buildmaster\Working\TestApp']]></message><duration>711.02240000000006</duration></task><duration>761.09440000000006</duration></target><failure><builderror><type>NAnt.Core.BuildException</type><message><![CDATA['vb6' failed to start.]]></message><location><filename>\\buildmaster\Working\TestApp\TestApp.build</filename><linenumber>39</linenumber><columnnumber>4</columnnumber></location><stacktrace><![CDATA[ at NAnt.Core.Tasks.ExternalProgramBase.StartProcess() in c:\Nant\src\NAnt.Core\Tasks\ExternalProgramBase.cs:line 501
at NAnt.Core.Tasks.ExternalProgramBase.ExecuteTask() in c:\Nant\src\NAnt.Core\Tasks\ExternalProgramBase.cs:line 386
at NAnt.Contrib.Tasks.Vb6Task.ExecuteTask() in c:\Nant\contrib\src\Tasks\Vb6Task.cs:line 220
at NAnt.Core.Task.Execute() in c:\Nant\src\NAnt.Core\Task.cs:line 186
at NAnt.Core.Target.Execute() in c:\Nant\src\NAnt.Core\Target.cs:line 247
at NAnt.Core.Project.Execute(String targetName, Boolean forceDependencies) in c:\Nant\src\NAnt.Core\Project.cs:line 910
at NAnt.Core.Project.Execute() in c:\Nant\src\NAnt.Core\Project.cs:line 862
at NAnt.Core.Project.Run() in c:\Nant\src\NAnt.Core\Project.cs:line 947]]></stacktrace><internalerror><type>System.ComponentModel.Win32Exception</type><message><![CDATA[The system cannot find the file specified]]></message><stacktrace><![CDATA[ at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at NAnt.Core.Tasks.ExternalProgramBase.StartProcess() in c:\Nant\src\NAnt.Core\Tasks\ExternalProgramBase.cs:line 498]]></stacktrace></internalerror></builderror></failure><duration>1211.7424</duration></buildresults>
Obviously, the meat of the exception is [CDATA['vb6' failed to start.]]. My problem is that when I run the Nant build directly on BuildMaster it completes the build successfully every time.
For the sake of completeness, here's my NAnt build script:
<?xml version="1.0" ?>
<project name="TestApp" default="build">
<!-- set build.date property to current date in format yyyy-MM-dd -->
<tstamp property="build.date" pattern="yyyy-MM-dd" />
<!-- global project settings -->
<property name="project.name" value="TestApp" />
<property name="project.version" value="1.00" unless="${property::exists('project.version')}" />
<property name="project.release.type" value="release" unless="${property::exists('project.release.type')}" /> <!-- nightly / dev / alpha / beta# / rc# / release -->
<property name="build.warnaserror" value="false" />
<!-- default configuration -->
<property name="project.client" value="" />
<property name="build.defines" value="" />
<property name="build.number" value="${math::abs(math::floor(timespan::get-total-days(datetime::now() - datetime::parse('01/01/2000'))))}" />
<!-- platform specific properties. These are the defaults -->
<property name="current.build.defines" value="${build.defines}" />
<!-- Build Tasks -->
<target name="init" description="Initializes build properties">
<property name="build.dir" value="${project::get-base-directory()}\build" />
<echo message="Build Directory is ${build.dir}" />
</target>
<target name="clean" depends="init" description="Deletes current build configuration">
<echo message="Clearing out files before recompiling..." />
<delete verbose="true">
<fileset basedir="${build.dir}">
<include name="TestApp*.exe" />
</fileset>
</delete>
</target>
<target name="build" depends="clean" description="Perform a build of the base TestApp product">
<mkdir dir="${build.dir}" unless="${directory::exists(build.dir)}" />
<!-- Actually compile VB6 project into executable -->
<vb6 project="TestApp.vbp" outdir="${build.dir}" errorfile="TestApp.build.err" verbose="true" />
</target>
</project>
Your help is greatly appreciated!
I might be misinterpreting your question so please bear with me. CCNet's nant task operatates on the local machine (the machine running CCNet).
If ToolBox is running CCNet but BuildMaster is running all tools (i.e. VB6, etc), I'm fairly sure there no way to do what's being attempted. Generally, CCNet needs to be running on the machine actually performing the builds. Therefore, the fact that VB6 cannot be found is because VB6 is not installed on ToolBox.
However, CCNet does have a way to monitor/control multiple build servers from one. So in your case you could configure ToolBox to control BuildMaster's builds, but CCNet would need to be installed on both. For a reference on something like this you can check out Splitting the build on CCNet's site.

How do I create a ZIP file of my Cruise Control builds?

I use CruiseControl.NET to automatically build my .NET 3.5 web applications, which works a treat. However, is there any way to automatically create a ZIP file of these builds, and put the ZIP's into a separate directory?
I have seen this is possible using NAnt but cannot find an example of how to get this working.
Can anyone offer help/examples?
I've just added such a Nant task to our CC machine.
See http://nant.sourceforge.net/release/latest/help/tasks/zip.html
Note when initially viewing the zip archive, it may appear as if all the files are at the same level, i.e no folders, but actually they folders are preserved.
Notice how you can exclude file types or folders.
You could take the approach of only including the file types you want and excluding the rest.
First define properties for where the source files are allcode.dir and the name and location of the zip file sourcebackup.zip
Now here is the nant task
<zip zipfile="${sourcebackup.zip}" includeemptydirs="true" verbose="true">
<fileset basedir="${allcode.dir}">
<include name="**/*" />
<exclude name="**/_resharper*/**" />
<exclude name="**/build/**" />
<exclude name="**/obj/**" />
<exclude name="**/bin/**" />
<exclude name="**/*.dll" />
<exclude name="**/*.scc" />
<exclude name="**/*.log" />
<exclude name="**/*.vssscc" />
<exclude name="**/*.suo" />
<exclude name="**/*.user" />
<exclude name="**/*.pdb" />
<exclude name="**/*.cache" />
<exclude name="**/*.vspscc" />
<exclude name="**/*.msi" />
<exclude name="**/*.irs" />
<exclude name="**/*.exe" />
</fileset>
<echo message="########## Zipped##########" />
Call this from your cc build like any other nant task.
We find it best if each CC project calls a single task if possible, then you only have to change the nant script, and you can run the nant script on your local machine.
Eg in the project block, we have the single target "build", which as part of its work calls ZipSource
<targetList>
<target>Build</target>
</targetList>
We use the above for a BizTalk project.
Enjoy.
If you're using Nant, then doesn't the Zip task work for you?
We are zipping the sources of a CruiseControl.NET project
but we are using ant
<target name="zipProject">
<mkdir dir="output"/>
<zip destfile="output\sources.zip" basedir="C:\project\src" />
</target>
i don't know about nant but i would expect it to be similar
#David: The NAnt Zip task is what I'm after, yes, but I'm asking how to integrate it as part of an automatic CruiseControl.NET build. If you take a look at the NAnt documentation for the cruise control config it doesn't make it clear if I can run an NAnt task from inside the <tasks> XML node in my CruiseControl config - it only says that it can be part of a <schedule>.
I have found a few examples of setting up your CruiseControl config and a few examples of NAnt tasks but nothing that integrates the two: specifically, zipping up a CruiseControl build.
If anyone has some sample XML of their CruiseControl config, hooking up to an NAnt zip task, post samples here.
Cheers.

Resources