I am trying to set up dependencies for a set of Delphi packages, such at if Application A uses Package 1 and Package 2, and Application B uses Package 1 only, then only Application A is rebuilt when Package 2 is changed.
At the moment, I am using a Group File, and each Package and Application is built (re-linked), even if it or one of it's dependencies is not changed.
UPDATE:
Unit1.pas is in Package 1
Unit2.pas is in Package 2
Application A uses Package 1 and Package 2
Application B use Package 2
What I want is that if I change Unit1.pas, then ONLY Package 1 and Application B is rebuilt. make will do this, but I can't work out how MSBUILD could be made to work.
My worked example uses a group file, which might be the underlying problem.
OK, I think I have sorted this out. Groupprojs will always rebuild / relink, so that is not what I want.
I have created a targets file, such that it defines the 4 projects and the dependencies of each. It has to be all the dependencies, both code and binary (i.e. the packages).
Msbuild has an attribute 'DependsOnTarget', but this doesn't achieve what I want, so I have added dependencies on both the code and packages. The final build.targets file looks like this ...
<Project ToolsVersion="3.5"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Default">
<ItemGroup>
<Package1 Include=".\Package1\Package1.dproj"/>
<Package2 Include=".\Package2\Package2.dproj"/>
<App6 Include=".\App6\Project6.dproj"/>
<App7 Include=".\App7\Project7.dproj"/>
</ItemGroup>
<ItemGroup>
<Package1ExternalSourceFiles Include=".\Package1\*.pas" />
<Package2ExternalSourceFiles Include=".\Package2\*.pas" />
<App6ExternalSourceFiles Include=".\App6\*.pas" />
<App7ExternalSourceFiles Include=".\App7\*.pas" />
<Package1BinaryFiles Include=".\Package1\Win32\Release\Package1.bpl" />
<Package2BinaryFiles Include=".\Package2\Win32\Release\Package2.bpl" />
<App6BinaryFiles Include=".\App6\bin\Project6.exe" />
<App7BinaryFiles Include=".\App7\bin\Project7.exe" />
</ItemGroup>
<Target Name="App6" Inputs="#(App6ExternalSourceFiles);#(Package1BinaryFiles);#(Package2BinaryFiles)" Outputs="#(App6BinaryFiles)" DependsOnTargets="Package1;Package2">
<Message Text="App6" />
<MSBuild Projects="#(App6)"/>
</Target>
<Target Name="App7" Inputs="#(App7ExternalSourceFiles);#(Package1BinaryFiles)" Outputs="#(App7BinaryFiles)" DependsOnTargets="Package1">
<Message Text="App7" />
<MSBuild Projects="#(App7)"/>
</Target>
<Target Name="Package1" Inputs="#(Package1ExternalSourceFiles)" Outputs="#(Package1BinaryFiles)">
<Message Text="Package1" />
<MSBuild Projects="#(Package1)"/>
</Target>
<Target Name="Package2" Inputs="#(Package2ExternalSourceFiles)" Outputs="#(Package2BinaryFiles)">
<Message Text="Package2" />
<MSBuild Projects="#(Package2)"/>
</Target>
<Target Name="Build">
<CallTarget Targets="Package1;Package2;App6;App7"/>
</Target>
</Project>
Whether this is scalable I am not sure, we could potentially have a large number of projects and dependencies.
UPDATE: Actually the binary dependency on the Applications isn't needed, if they are shipped separate from the packages. Recompiling Package 1, without changing it's interface would mean that App6 and App7 are not rebuilt.
Related
Visual Studio 2019, .Net Standard 2.0
How do I include a custom msbuild targets file for the consuming project?
What is the official supported way of doing this?
I've already tried:
modifying the csproj file as per (Setting Nuget package target path for item in MSBuild project)
trying to specify a nuspec file as per (https://natemcmaster.com/blog/2017/11/11/build-tools-in-nuget/)
Nuspec:
<?xml version="1.0"?>
<package >
<metadata>
<id>TestingNugetContent</id>
<version>1.0.10</version>
<title>Blah</title>
<authors>Me</authors>
<owners>Me</owners>
<licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
<projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
<iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Blah</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2019</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="Immutable\*.*" target="content/Immutable/" />
<file src="Build\*.*" target="build/netstandard2.0/" />
</files>
</package>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<NoPackageAnalysis>true</NoPackageAnalysis>
<NuspecFile>TestingNugetContent.nuspec</NuspecFile>
<IntermediatePackDir>$(MSBuildProjectDirectory)/bin/$(Configuration)/publish/</IntermediatePackDir>
<PublishDir>$(IntermediatePackDir)$(TargetFramework)/</PublishDir>
<NuspecProperties>publishDir=$([MSBuild]::NormalizeDirectory($(IntermediatePackDir)))</NuspecProperties>
<Version>1.0.10</Version>
</PropertyGroup>
<ItemGroup>
<Compile Remove="build\**" />
<EmbeddedResource Remove="build\**" />
<None Remove="build\**" />
</ItemGroup>
<ItemGroup>
<None Include="build\netstandard2.0\TestingNugetContent.targets" />
</ItemGroup>
<Target Name="PublishAll" BeforeTargets="GenerateNuspec">
<ItemGroup>
<_TargetFramework Include="$(TargetFrameworks)" />
</ItemGroup>
<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="TargetFramework=%(_TargetFramework.Identity)" />
</Target>
</Project>
Checking the consumer's <***>.csproj.nuget.g.targets file the import project tag for this custom target is missing after installing the Nuget package
As per the docs, the props and targets file names must match the package id exactly. Your nuspec lists the <id> as TestingNugetContent, so the files must be TestingNugetContent.props and TestingNugetContent.targets. They should be either directly in the build/ folder in the package, or the build/<tfm>/ folder (I prefer to be more explicit, so I appriciate you used the netstandard2.0 TFM). Now, your csproj appears to specify a build\netstandard2.0\TestingNugetContent.targets, which looks correct, so I can only guess that it wasn't packed into the correct location somehow.
I don't currently have time to show an example on how to pack it, but you can inspect the contents of your nupkg using NuGet package explorer, or just opening it up as a zip file, see what's "wrong", then adjust your project and try again.
FYI, you shouldn't need to use a nuspec at all, you can use the MSBuild PackagePath metadata on items to specify where MSBuild items are packed. It's unclear to me what the purpose of your PublishAll target is supposed to be. If you added it as part of trying to get your targets file included, you can remove it.
I have an web project Project A and a library Project B.
Project B is being built into Project A\Plugins.
The Problem is when Project A is being built via CI Project B isn't deployed with Project A. MSBuild params in CI are:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\" /t:ProjectA
I added the following piece of code into Project A.csproj to deploy Project B with A:
<ItemGroup>
<ProjectsToBuild Include="..\..\Plugins\**\*ProjectB*proj" />
</ItemGroup>
<Target Name="Plugin" AfterTargets="Build">
<Message Text="Building Plugins" Importance="High" />
<MSBuild Projects="#(ProjectsToBuild)" ContinueOnError="false" Properties="Configuration=$(Configuration)">
<Output ItemName="OutputFiles" TaskParameter="TargetOutputs" />
</MSBuild>
<CallTarget Targets="CopyPlugins"/>
</Target>
<PropertyGroup>
<PluginDirectory>Plugins</PluginDirectory>
</PropertyGroup>
<Target Name="CopyPlugins">
<Message Text="Copying plugins to $(_PackageTempDir)\Plugins\ ($(ProjectDir)$(PluginDirectory))" Importance="high" />
<CreateItem Include="$(ProjectDir)$(PluginDirectory)\**\*.*">
<Output TaskParameter="Include" ItemName="PluginFiles" />
</CreateItem>
<Copy DestinationFolder="$(_PackageTempDir)\Plugins\" SourceFiles="#(PluginFiles)" SkipUnchangedFiles="true" />
</Target>
In the log executing order seems fine (Copy after Build), but after being deployed the Plugin folder doesn't exist on the target server.
Am I missing anything?
The files need to be included in the project. Since the files are generated dynamically, you can add this code to project file (e.g. XX.csproj)
<Content Include="plugin\**\*.*" />
From your description, you would need to check in Project A\Plugins folder into TFS. But it's not suggested.
We suggest you make a project reference in the same solution or create NuGet for package management. It's recommended to build a nuget package for Project B, and publish this Nuget package, then restore the library to Project A when you build it.
We are looking at migrating our build machine from FinalBuilder to Jenkins to fit in with the rest of our extended company.
One issue that I have noticed is that whereas Finalbuilder is able to extract the current library path from your current Delphi installs on the build machine, Jenkins relies on the information contained within the .dproj files.
Owing to known problems of the paths within the .dproj files being very specific to a users machine, we don't currently commit them to our repository, relying on Delphi to re-create them as required. This obviously doesn't play nice when the build machine is reliant on a full MSBUILD script being there in the first place.
We use a fair few third-party components (DevExpress suite alone having over 100 units), so including and maintaining all the .pas files with full paths in the .dpr isn't really an option for this.
Does anyone have a tried-and-tested solution for this?
My thoughts on options were:
setting the %PATH% for each build - adding the current Delphi library
for the relevant version (will this run into %PATH% length restrictions?)
Using a command-line parameter to pass the correct library path to MSBUILD (is this possible?)
Including the search path somehow in the source files with compiler directives (is this possible?)
Using a pre-compile step to create new .dproj files (something like http://delphi-divining.blogspot.co.uk/2012/10/dprojmaker-tool-to-create-delphi.html but it'll need to be command-line)
Edit: 5th idea:
Could we use dproj.local files for each project, stored in a separate repository (or in a separate path) and copied to the build machine pre-build? This would allow build machine paths to be stored safely away from clutzy commits.
You need to submit your .dproj file to source control.
You have a problem which is that your configuration is not complete. Any build system should be able to build your project using nothing but files in your source control, that is the ONLY way to ensure you are building the correct binary.
You have a number of options to make this work
You can use Environment variables in the Delphi IDE eg %ROOTFOLDER% could be set to C:\Development\MyDelphiProjects on one machine and C:\Dev on another and as long as everything is the same from that route it should be ok. Each dev and your build machine can set the required path. You may need vars for bpl paths also.
Enforce identical structures on client machines. Really how difficult is it to make all devs us C:\Development\Delphi as their root?
Make sure all search paths are relative. This can work, but there are always exceptions that cause problems so I have never managed to get this to work.
We used option 1 in a previous company and it worked very successfully, its a bit of a pain to set up but once setup you can be sure your build is correct.
I had the same problem when i choose Jenkins as a "build" environment. The solution is to use a MSBuild script with a build task inside. So in Jenkins instead of building the project directly, just build this script which gives you a lot more options, including the option to specify the paths for the project (you can to override the default IDE paths).
I'll post such a script tomorrow.
So in Jenkins when you configure MSBuild you have to specify the msbuild file, which will be Build.xml. For command line arguments i use only /v - verbosity and /t - target name.
The build script looks like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<Target Name="Compile" DependsOnTargets="CompileApp" />
<PropertyGroup>
<ExeOutputName>App.exe</ExeOutputName>
<ExeOutputPath>x:\exe</ExeOutputPath>
<DcuOutputPath>x:\dcu</DcuOutputPath>
<ForConfig>Release</ForConfig>
<ForPlatform>Win32</ForPlatform>
</PropertyGroup>
<Target Name="ResolveOutputPath">
<MakeDir Directories="$(ExeOutputPath)" />
<MakeDir Directories="$(DcuOutputPath)" />
<Delete Files="$(ExeOutputPath)\$(ExeOutputName)" />
<Delete Files="$(DcuOutputPath)\*.*" />
</Target>
<ItemGroup>
<AppUnitSearchPathItem Include="$(BDS)\lib\$(ForPlatform)\$(ForConfig)" />
<AppUnitSearchPathItem Include="C:\Users\builder\Documents\tmssoftware\TMS Component Pack" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\RemObjects Software\RemObjects SDK for Delphi\Dcu\$(ForPlatform)" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\RemObjects Software\RemObjects SDK for Delphi\Source" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\RemObjects Software\RemObjects SDK for Delphi\Source\CodeGen" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\RemObjects Software\RemObjects SDK for Delphi\Source\DataSnap" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\RemObjects Software\RemObjects SDK for Delphi\Source\ZLib" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\RemObjects Software\RemObjects SDK for Delphi\Source\Synapse" />
<AppUnitSearchPathItem Include="C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\Components\EhLib\Lib\$(ForPlatform)\$(ForConfig)" />
...
</ItemGroup>
<ItemGroup>
<AppDefinesItem Include="App" />
<!-- AppDefinesItem Include="CompilerDirective" -->
</ItemGroup>
<ItemGroup>
<AppPropertiesItem Include="DCC_ExeOutput=$(ExeOutputPath)" />
<AppPropertiesItem Include="DCC_DcuOutput=$(DcuOutputPath)" />
<AppPropertiesItem Include="DCC_BuildAllUnits=true" />
<AppPropertiesItem Include="DCC_Optimize=true" />
<AppPropertiesItem Include="DCC_DebugInformation=0" />
<AppPropertiesItem Include="DCC_PentiumSafeDivide=true" />
<AppPropertiesItem Include="DCC_RangeChecking=true" />
<AppPropertiesItem Include="DCC_IntegerOverflowCheck=true" />
<AppPropertiesItem Include="DCC_WriteableConstants=true" />
<AppPropertiesItem Include="DCC_IOChecking=true" />
<AppPropertiesItem Include="DCC_AssertionsAtRuntime=false" />
<AppPropertiesItem Include="DCC_Warnings=true" />
<AppPropertiesItem Include="DCC_MapFile=3" />
<AppPropertiesItem Include="DCC_ConsoleTarget=false" />
</ItemGroup>
<Target Name="CompileApp" DependsOnTargets="ResolveOutputPath">
<PropertyGroup>
<AppUnitSearchPath>#(AppUnitSearchPathItem)</AppUnitSearchPath>
<AppDefines>#(AppDefinesItem)</AppDefines>
</PropertyGroup>
<ItemGroup>
<AppProperties Include="Config=$(ForConfig)" />
<AppProperties Include="Platform=$(ForPlatform)" />
<!-- AppProperties Include="LibraryPath=$(AppUnitSearchPath)" -->
<AppProperties Include="DelphiLibraryPath=$(AppUnitSearchPath)" />
<AppProperties Include="UnitSearchPath=$(AppUnitSearchPath)" />
<AppProperties Include="ResourcePath=$(AppUnitSearchPath)" />
<AppProperties Include="IncludePath=$(AppUnitSearchPath)" />
<AppProperties Include="ObjPath=$(AppUnitSearchPath)" />
<AppProperties Include="DCC_Define=$(AppDefines)" />
<AppProperties Include="#(AppPropertiesItem)" />
</ItemGroup>
<MSBuild Projects="App.dproj" Properties="#(AppProperties)" />
</Target>
</Project>
What is missing here is the versioning part which can be done from this script using a resource template...
This is a follow-up to: BlackBerry - use own JAR file in own project & BlackBerry - Ant build script for more complex apps. This problem has now been solved below.
Aim
I want to:
use Ant (bb-ant-tools) to build my library into a JAR file
include that JAR file in a project
use Ant to build that project into a COD that will run on the device (without external COD files).
The important part is to use Ant to do the final stage of the build.
All posts I have found for this problem use Eclipse for that final build stage (details at BlackBerry - use own JAR file in own project).
Progress
I can build the library project into a JAR using Ant.
In Eclipse, I can add that JAR file to a project, and build it as desired (single COD, no external dependencies). It will run on the device.
In Ant, I can also make a build that relies on an extra COD library to contain the runtime code - this is close to what I need.
Problem
I can build the final project with Ant. But the resulting COD file does not include any runtime code from my library.
Many posts I have read show how this can be done using extra COD files for the library. I would like to avoid this.
How can I include a JAR into my project without external dependencies, using Ant? I believe this is possible because I can do it using Eclipse.
Workaround
My current workaround is to include my SDK / library project as source code (as per esaj's answer below), rather than as a JAR file. This has some disadvantages over the JAR approach, but I have a build that runs on the device successfully.
(I hope its OK to cross-reference this question with the following long list of links?)
StackOverflow links:
Continuous Integration server for blackberry development? (and certificate signing) (I haven't had time to go through this one, but I think it looks promising)
Blackberry: Verificattion error when using Library project as External Jar
https://stackoverflow.com/questions/6134940/how-to-use-external-library-jar-file-in-blackberry
Blackberry 5.0 - Add reference to a Java Library Project
How to add external jar or zip file in the Blackberry project
Blackberry Apps - Importing a code-signed jar into an application project
How to add library project with the current development project in blackberry
This one gives other links - quite useful:
Handling dependencies in blackberry development
These not so useful:
In Blackberry, can we create common library that can be used by different applications?
BlackBerry Facebook SDK jar file
Adding and Testing Compatibility of External Jar to Blackberry Project
How to attach Jar in Blackberry
BlackBerry RIMAPPSA2 signing key required -- why?
Is there a list of classes, methods and API which will trigger RIMAPPSA2 permission when signing Blackberry application?
RIM:
javac -target parameter used by the rapc.exe tool
Add a .jar file dependency
Other jar added in BB project - using BB ant tools
Tutorial: How To Use 3rd Party Libraries in your Applications
Have you tried pointing to the library in the src section under rapc?
E.g.:
<rapc ...>
<src>
<fileset dir="${buildDirectory}">
<include name="src/**/*.rrh" />
<include name="src/**/*.rrc" />
<include name="src/**/*.java" />
<include name="res/**/*.*" />
<!-- Libraries -->
<include name="lib/**/*.*" />
</fileset>
</src>
</rapc>
I had a similar problem last year, I had created a "framework" that was used as a base for multiple BB-applications, but run into problems with multiple CODs (I don't remember exactly what, something like the device refused to install multiple applications that had same external cods, if the external CODs weren't installed separately first, and then the applications). As the applications could be installed separately (one person might install only app A, another might install only app B, and yet another might install both A and B), the whole framework needed to be included in all the apps using it. I cooked up this Ant-script using bb-ant-tools (hopefully I didn't break anything removing some stuff specific to our apps and obfuscating package names etc):
<?xml version="1.0" encoding="UTF-8"?>
<project name="${description}" default="build" basedir=".">
<taskdef resource="bb-ant-defs.xml" classpath="lib/bb-ant-tools.jar" />
<!-- rapc and sigtool require the jde.home property to be set -->
<!-- NOTE: You may need to copy the signature files from Eclipse\plugins\net.rim.ejde\vmTools to the components\bin -dir
if the keys were installed using the Eclipse-plugin -->
<property name="jdehome" value="C:\BB\Eclipse\plugins\net.rim.ejde.componentpack5.0.0_5.0.0.25\components" />
<!-- Framework source locations, these must be set correctly -->
<property name="frameworkRes.dir" value="C:\BB\workspace\BB_Framework\res" />
<property name="frameworkSrc.dir" value="C:\BB\workspace\BB_Framework\src\com\whatever\frame" />
<!-- Locations for simulator, binaries, jde home, don't touch these -->
<property name="simulator" value="${jdehome}\simulator" />
<property name="bin" value="${jdehome}\bin" />
<property name="jde.home" location="${jdehome}" />
<!-- directory of simulator to copy files to -->
<property name="simulator.home" location="${simulator}" />
<property name="src.dir" location="src" />
<property name="build.dir" location="build" />
<property name="temp.dir" location="C:\tempsrc" />
<!-- Project specific -->
<!-- Application title -->
<property name="app.title" value="Application Name" />
<property name="app.version" value="1.0.0" />
<!-- Value to prepend before frame-class packages -->
<property name="frame.prefix" value="appname" />
<!-- Name of the COD to produce -->
<property name="cod.name" value="Appname" />
<target name="build">
<mkdir dir="${build.dir}" />
<delete dir="${temp.dir}" />
<mkdir dir="${temp.dir}" />
<mkdir dir="${temp.dir}\${frame.prefix}" />
<copy toDir="${temp.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</copy>
<copy toDir="${temp.dir}\${frame.prefix}">
<fileset dir="${frameworkSrc.dir}">
<include name="**/*.java" />
</fileset>
</copy>
<copy toDir="${temp.dir}\res">
<fileset dir="${frameworkRes.dir}">
<include name="**/*" />
</fileset>
</copy>
<copy toDir="${temp.dir}\res">
<fileset dir="res">
<include name="**/*" />
</fileset>
</copy>
<!-- This replaces the package names for classes copied from under framework-directory to ${frame.prefix} -directory -->
<replace dir="${temp.dir}" value="${frame.prefix}">
<include name="**/*.java"/>
<replacetoken>com.whatever.frame</replacetoken>
</replace>
<rapc output="${cod.name}" srcdir="${temp.dir}" destdir="${build.dir}">
<jdp title="${app.title}"
version="${app.version}"
vendor="Your Company"
icon="../res/img/icon.png"
/>
</rapc>
</target>
<target name="sign">
<sigtool codfile="${build.dir}/${cod.name}.cod" />
</target>
<target name="clean">
<delete dir="${build.dir}" />
</target>
<target name="load-simulator" depends="build">
<copy todir="${simulator.home}">
<fileset dir="${build.dir}" includes="*.cod,*.cso,*.debug,*.jad,*.jar" />
</copy>
</target>
</project>
What this does, is copy all the java-files and resources from your current project and then from the framework-project to a temporary directory, replacing package names on the way for the frame-work files (as they're put into a separately named directory), this has to do with the fact that the devices also refused to install multiple applications that had same classes under same packages (namely, the framework classes, for your case this might not be necessary). After the copying and replacing is done, the application is built to target build-directory using rapc. There are separate tasks for signing, cleaning and loading the app to a simulator. Hope this helps.
I am trying to create a custom MSBuild task that will run my nUnit tests either locally or during a TFS2010 build. The script works great locally but I can't seem to find the test dlls on the TFS build server. I'm using a task in the MSBuild.ExtensionPack to run the unit tests (again this works fine locally).
The Assemblies list is always empty. TargetDir shows the path is "C:\Builds\2\Product1\ci.product1.acme.com\Binaries\" which looks right to me. I also tried to kick off my target after the CoreCompile target instead within the AfterBuild target with no change.
I've probably made some stupid mistake but I'm in kill me mode at this point. Please help.
<PropertyGroup>
<RunTFSBuild>false</RunTFSBuild>
<SolutionDirectory>$(MSBuildProjectDirectory)\..</SolutionDirectory>
<ExtensionTasksPath>$(SolutionDirectory)\_shared\MSBuild\</ExtensionTasksPath>
<TPath>$(ExtensionTasksPath)MSBuild.ExtensionPack.tasks</TPath>
<NUnitOutputFile>$(SolutionDirectory)\nUnitResults.xml</NUnitOutputFile>
<NUnitOutputFileAsMsTest>$(SolutionDirectory)\nUnitResultsAsMsTestResults.xml</NUnitOutputFileAsMsTest>
<ToolPath>$(SolutionDirectory)\_shared\MSBuild\nUnit_2.5.7</ToolPath>
</PropertyGroup>
<Import Project="$(TPath)" />
<Target Name="AfterBuild">
<CallTarget Condition="$(RunTFSBuild)!='true'" Targets="NUnitTestRunner" />
<CallTarget Condition="$(RunTFSBuild)=='true'" Targets="NUnitTestRunner;TFSNUnitTestRunner" />
</Target>
<Target Name="NUnitTestRunner">
<ItemGroup >
<Assemblies Include="$(SolutionDirectory)\**\bin\$(Configuration)\*.nUnit.Tests.dll" />
</ItemGroup>
<ItemGroup Condition="$(RunTFSBuild)=='true'">
<Assemblies Include="$(TargetDir)\**\*.nUnit.Tests.dll" />
</ItemGroup>
<Message Text="SolutionDirectory=$(SolutionDirectory)" />
<Message Text="ExtensionTasksPath=$(ExtensionTasksPath)" />
<Message Text="TargetDir=$(TargetDir)" />
<Message Text="TPath=$(TPath)" />
<Message Text="NUnitOutputFile=$(NUnitOutputFile)" />
<Message Text="Running nUnit tests from: $(Assemblies)" />
1) Try to change property RunTFSBuild
<RunTFSBuild Condition="'$(RunTFSBuild)'==''">false</RunTFSBuild>
2) Replace sections (it may be just cleaning of project, but it may be very important due to some limitations of CallTarget):
<Target Name="AfterBuild" DependsOnTargets="NUnitTestRunner;TFSNUnitTestRunner" />
<Target Name="TFSNUnitTestRunner"
Condition="$(RunTFSBuild)=='true'">
<!-- TFSNUnitTestRunner Body -->
</Target>
3) If 1) and 2) willn't be helpful try to set verbose of the build to diagnostic (msbuld key /v:diag). Find all calls of TFSNUnitTestRunner in the log and you will see what is actually happened on TFS.
EDIT: *Assemblies* is declared as ItemGroup. Use #(Assemblies) to access items:
<Message Text="Running nUnit tests from: #(Assemblies)" />
Property $(Assemblies) will always be empty in your case.