0

I'm setting up CI builds on TFS. A team member developers doesn't like idea of unloading the .wixproj file to edit the msbuild definition (because it is 'hidden') and I kind of agree with this.

So he has created a separate setup.build file which he calls with:

msbuild /t:Build;PublishWebsite;Harvest;WIX setup.build

The contents of which are below:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
       xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebSiteSource>..\InstoreApplications\</WebSiteSource>
    <SetupF>..\Setup\</SetupF>
    <PublishF>publish\</PublishF>
    <Publish>$(SetupF)$(PublishF)</Publish>
    <WebSiteContentCode>WebSiteContent.wxs</WebSiteContentCode>
    <WebSiteContentObject>WebSiteContent.wixobj</WebSiteContentObject>
    <!--<MsiOut>bin\\Release\\INT SMK Coles Store WebApi 1.0.1.msi</MsiOut>-->
    <MsiName>INT SMK Instore Applications 1.0.2.msi</MsiName>
    <MsiOut>bin\Release\$(MsiName)</MsiOut>
  </PropertyGroup>

  <!-- Defining group of temporary files which is the content of the web site. -->
  <ItemGroup>
    <WebSiteContent Include="$(WebSiteContentCode)" />
  </ItemGroup>

  <!-- The list of WIX input files -->
  <ItemGroup>
    <WixCode Include="Product.wxs" />
    <WixCode Include="$(WebSiteContentCode)" />
    <WixCode Include="WebAPIDlg.wxs" />
    <WixCode Include="IISConfiguration.wxs" />
    <WixCode Include="WixUI_InstallDirNoLicense.wxs" />
  </ItemGroup>

  <!-- The list of WIX after candle files -->
  <ItemGroup>
    <WixObject Include="Product.wixobj" />
    <WixObject Include="$(WebSiteContentObject)" />
    <WixObject Include="WebAPIDlg.wixobj" />
    <WixObject Include="IISConfiguration.wixobj" />
    <WixObject Include="WixUI_InstallDirNoLicense.wixobj" />
  </ItemGroup>

  <!-- Define default target with name 'Build' -->
  <Target Name="Build">
    <!-- Compile whole solution in release mode -->
    <MSBuild
        Projects="..\InstoreApplications.sln"
        Targets="ReBuild"
        Properties="Configuration=Release" />
  </Target>

  <Target Name="PublishWebsite">
    <!-- Remove complete publish folder in order to 
             be sure that evrything will be newly compiled -->
    <Message Text="Removing publish directory: $(SetupF)"/>
    <RemoveDir Directories="$(SetupF)" ContinueOnError="false" />
    <Message Text="Start to publish website" Importance="high" />
    <MSBuild
        Projects="..\\InstoreApplications\InstoreApplications.csproj"
        Targets="ResolveReferences;_CopyWebApplication"
        Properties="Configuration=Release;WebProjectOutputDir=$(Publish)\;OutDir=$(Publish)bin\;" />
  </Target>
  <!-- Define creating installer in another target -->
  <Target Name="Harvest">
    <!-- Harvest all content of published result -->
    <Exec
        Command='"$(Wix)bin\heat" dir $(Publish) -dr INSTALLDIR -ke -srd -cg ApplicationComponents -var var.publishDir -gg -out $(WebSiteContentCode)'
        ContinueOnError="false"
        WorkingDirectory="." />
  </Target>
  <Target Name="WIX">
    <!--     At last create an installer -->
    <Exec
        Command='"$(Wix)bin\candle" -ext WixIISExtension -ext WixUtilExtension -ext WixSqlExtension -dpublishDir=$(Publish) -dMyWebResourceDir=. @(WixCode, &apos; &apos;)'
        ContinueOnError="false"
        WorkingDirectory="." />
    <Exec
        Command='"$(Wix)bin\light" -ext WixIISExtension -ext WixUIExtension -ext WixUtilExtension -ext WixSqlExtension -out "$(MsiOut)" @(WixObject, &apos; &apos;)'
        ContinueOnError="false"
        WorkingDirectory="." />

    <!-- A message at the end -->
    <Message Text="Install package has been created." />
  </Target>
  <!-- Optional target for deleting temporary files. Usually after build -->
  <Target Name="DeleteTmpFiles">
    <RemoveDir Directories="$(Publish)" ContinueOnError="false" />
    <RemoveDir Directories="$(SetupF)" ContinueOnError="false" />
    <Delete Files="@(WixObject);@(WebSiteContent)" />
  </Target>

</Project>

This works absolutely fine on local machine.

For the TFS build I reference the setup.build file directly in the build defination and pass in the: "/t:Build;PublishWebsite;Harvest;WIX" in Advanced>MSBuild Arguments ...this produces a 'success' build however the build is no longer producing an MSI.

I believe the issue is between the HEAT generation of files and WIX picking these files up, note the variables:

<SetupF>..\Setup\</SetupF>
<PublishF>publish\</PublishF>
<Publish>$(SetupF)$(PublishF)</Publish>

The HEAT command does produce a folder with files on the build server, the folder ends up under /src rather than /bin and this is logically the same as building locally

However as the path is relative and I am guessing the WIX candle and/or light commands need their WorkingDirectory changed?...Is there a way to do this and not break the local build and not hardcode the path?

Yan Sklyarenko
  • 31,557
  • 24
  • 104
  • 139
Darren
  • 9,014
  • 2
  • 39
  • 50

1 Answers1

0

Yes, use a condition to let a property use a different value on a desktop build compared to TFS Team Build (see documentation).

If your script is run from within Visual Studio, check the BuildingInsideVisualStudio MSBuild property.

In TFS 20102, you usually customize your Build workflow to pass an MSBuild script workflow variables (e.g. Pass Relative Path Arguments to MSBuild in TFS2010 Team Build). In TFS 2013 is much easier as you have a lot of useful environment properties (see documentation).

Giulio Vian
  • 8,248
  • 2
  • 33
  • 41