tfsmsbuildmsbuild-taskmsbuildcommunitytasks

MSBUILD script should zip all assemblies in solution after build, but only gets some DLLs (under local and TFS build)


I want to set up my VS solution so at the end of the build, the installable files are zipped up for easy distribution. This should work under either a local build, or a TFS build. This is set up as follows:

<!-- Set package name and input/output folders -->
<PropertyGroup>
    <PackageName>MyAppService</PackageName>
    <BuildTargetFolder>$(TargetDir)</BuildTargetFolder>
    <PackageOutputFolder>$(OutDir)</PackageOutputFolder>
</PropertyGroup>

<!-- Set location of files -->
<ItemGroup>
    <MyAppBinaries Include="$(BuildTargetFolder)*.exe$(BuildTargetFolder)*.dll;" Exclude="$(BuildTargetFolder)MyApp.Packaging.dll" />
    <MyAppOtherFiles Include="$(SolutionDir)MyApp.Packaging\InstallService.bat;$(SolutionDir)MyApp.Packaging\UnInstallService.bat;$(BuildTargetFolder)MyApp.HostService.exe.config" />
    <MyAppContracts Include="$(BuildTargetFolder)MyApp.Common.DataContext.dll;$(BuildTargetFolder)MyApp.Common.Shared.dll" />
</ItemGroup>

<!-- After building (in Release mode only), build the installation package -->
<Target Name="AfterBuild">
    <CallTarget Targets="BuildPackage" Condition="'$(Configuration)'=='Release'" />
</Target>

<!-- Build the package -->
<Target Name="BuildPackage">
    <!-- Package for installing the MyApp Service -->
    <Zip Files="@(MyAppBinaries);@(MyAppOtherFiles)" Flatten="True" WorkingDirectory="$(MSBuildProjectDirectory)" ZipFileName="$(PackageOutputFolder)\$(PackageName)_$(Major).$(Minor).$(Revision)_Install.zip" />
    <!-- Package for MyApp Contracts -->
    <Zip Files="@(MyAppContracts)" Flatten="True" WorkingDirectory="$(MSBuildProjectDirectory)" ZipFileName="$(PackageOutputFolder)\$(PackageName)_MyAppContracts_$(Major).$(Minor).$(Revision)_Install.zip" />
</Target>

The ZIP files are created in the TFS drop location when TFS does the build, or the Packaging project's bin folder for a local build.

The second ZIP (containing 2 DLLs) always gets created OK, under local and TFS build.

The problem is that when TFS does the build, the first ZIP contains no EXE and only 2 of the 23 DLLs (and all 3 of the files identified by MyAppOtherFiles). When the build is done locally (and the the Packaging project's bin folder is emptied first), the first ZIP contains no EXE or DLLs, and only the 2 .bat files identified by MyAppOtherFiles.

If I change BuildTargetFolder from $(TargetDir) to $(OutDir), I get the same result.

The TFS build definition uses an unmodified Default Template.

It is as if when TFS does the build, the Packaging project is the 3rd project to be built, rather than the last, therefore only zipping 2 DLLs. However, the solution checked into TFS is exactly the same as what I build locally, and in that case it seems the script cannot see ANY of the binaries. If the local build is done again (without emptying the Packaging project's bin folder), the ZIPs then contain all the required files, but this is obviously because after the 1st build the bin folder now contains the EXE & all the DLLs.

Its also confusing that under a TFS build the MyApp.HostService.exe.config (which is produced by the build) is zipped, but not the MyApp.HostService.exe. And why is the 2nd ZIP always created OK, when it contains DLLs that are skipped in the 1st ZIP ????? I have tried swapping the order the ZIPs are created, but it makes no difference!

What can I do to ensure that the zipping is always done after all the projects are built, under both local and a TFS build?

Thanks


Solution

  • Make sure you set the packaging project dependency on the solution depend on the other projects this way it will always build the others first, thus leaving you with the packaging last.

    enter image description here