You can define properties in one target, and use their values in the other... For example, you can define
<target name="run-unit-tests">
<property name="test.executable" value="tools\nunit\nunit-console.exe"/>
<property name="test.extratestargs" value="foo,bar,baz"/>
<call target="do-unit-tests"/>
</target>
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="test.extrtestargs" value="foo,baz,quux,xyzzy"/>
<call target="do-unit-tests"/>
</target>
<target name="do-unit-test-coverage">
<property name="test.args" value="${test.assemblies} ${test.extratestargs} <!--snip -->" />
<ncover <!--snip -->
commandLineArgs="${test.args}" >
<!--snip-->
</ncover>
</target>
Or if you need them to be structured completely differently, not just have some different values, take advantage of the fact that the property substitution is delayed:
<?xml version="1.0"?>
<project name="nanttest">
<target name="run-unit-tests">
<property name="test.executable" value="tools\nunit\nunit-console.exe"/>
<property name="test.args" value="foo bar -assembly ${test.assemblies} baz" dynamic="true"/>
<call target="do-unit-test"/>
</target>
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="test.args" value="foo,baz,quux /a:${test.assemblies} xyzzy" dynamic="true"/>
<call target="do-unit-test"/>
</target>
<target name="do-unit-test-coverage">
<echo message="test.executable = ${test.executable}, test.args = ${test.args}" />
</target>
<target name="do-unit-test">
<property name="test.assemblies" value="MyProject.dll"/>
<call target="do-unit-test-coverage" />
</target>
</project>
user@host:/tmp/anttest$ nant run-unit-tests
[...snip...]
run-unit-tests:
do-unit-test:
do-unit-test-coverage:
[echo] test.executable = tools\nunit\nunit-console.exe, test.args = foo bar -assembly MyProject.dll baz
BUILD SUCCEEDED
Total time: 0 seconds.
user@host:/tmp/anttest$ nant -D:teamcity.dotnet.nunitlauncher=nunitlauncher run-unit-tests-teamcity
[...snip...]
run-unit-tests-teamcity:
do-unit-test:
do-unit-test-coverage:
[echo] test.executable = nunitlauncher, test.args = foo,baz,quux /a:MyProject.dll xyzzy
BUILD SUCCEEDED
Total time: 0 seconds.
If you really, really just need to know if you're running in TeamCity, then this should help:
<target name="run-unit-tests-teamcity">
<property name="test.executable" value="${teamcity.dotnet.nunitlauncher}"/>
<property name="running.in.teamcity" value="true"/>
<call target="do-unit-tests"/>
</target>
See Build Script Interaction with TeamCity topic.
You can report messages for build log in the following way:
##teamcity[message text='<message text>' errorDetails='<error details>' status='<status value>']
where:
- The status attribute may take following values: NORMAL, WARNING,
FAILURE, ERROR. The default value is NORMAL.
- The errorDetails
attribute is used only if status is ERROR, in other cases it is
ignored.
This message fails the build in case its status is ERROR and
"Fail build if an error message is logged by build runner" checkbox is
checked on build configuration general settings page. For example:
##teamcity[message text='Exception text' errorDetails='stack trace' status='ERROR']
Update 2013-08-30:
As of TeamCity 7.1 build failures should be reported using the buildProblem
service message instead:
##teamcity[buildProblem description='<description>' identity='<identity>']
Best Answer
I think the trycatch task is part of NantContrib. It is possible that NantContrib isn't included with team city anymore. Or your script needs an update reference to nantcontrib. Just a thought.