We deploy our app using TFS Teambuild. To deploy to multiple environments (dev, tst, acceptance and  production) we use solutionconfiguration and config transformations.

Because we want to leverage .NET 4.5 for multiple reasons we needed to use the Azure 1.8 sdk. I noticed the ServiceDefinition.csdef transformation was not working as before when deploying using the 1.8 azure sdk.

The .ccproj file contained the following xml:

<ItemGroup>
  <ServiceDefinition Include="ServiceDefinition.csdef" />
  <None Include="ServiceDefinition.Local.csdef" />
  <None Include="ServiceDefinition.Development.csdef" />
  <None Include="ServiceDefinition.Test.csdef" />
  <None Include="ServiceDefinition.Acceptance.csdef" />
  <None Include="ServiceDefinition.Release.csdef" />
  <ServiceConfiguration Include="ServiceConfiguration.cscfg" />
  <None Include="ServiceConfiguration.Local.cscfg" />
  <None Include="ServiceConfiguration.Development.cscfg" />
  <None Include="ServiceConfiguration.Test.cscfg" />
  <None Include="ServiceConfiguration.Acceptance.cscfg" />
  <None Include="ServiceConfiguration.Production.cscfg" />
  <None Include="ServiceConfiguration.Release.cscfg" />
</ItemGroup>
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<PropertyGroup>
  <ServiceConfigurationTransform>ServiceConfiguration.$(AzureDeployEnvironment).cscfg</ServiceConfigurationTransform>
</PropertyGroup>
<Target Name="TransformServiceConfiguration" BeforeTargets="ValidateServiceFiles" Condition="exists('$(ServiceConfigurationTransform)')">
  <TransformXml Source="@(ServiceConfiguration)" Destination="%(Filename)%(Extension).tmp" Transform="$(ServiceConfigurationTransform)" />
</Target>
<PropertyGroup>
  <ServiceDefinitionTransform>ServiceDefinition.$(AzureDeployEnvironment).csdef</ServiceDefinitionTransform>
</PropertyGroup>
<Target Name="TransformServiceDefinition" BeforeTargets="ValidateServiceFiles" Condition="exists('$(ServiceDefinitionTransform)')">
  <TransformXml Source="@(ServiceDefinition)" Destination="%(Filename)%(Extension).tmp" Transform="$(ServiceDefinitionTransform)" />
</Target>
<Target Name="CopyTransformedEnvironmentConfigurationXmlBuildServer" AfterTargets="AfterPackageComputeService" Condition="'$(AzureDeployEnvironment)'!='' and '$(IsDesktopBuild)'!='true' ">
  <Copy SourceFiles="ServiceConfiguration.cscfg.tmp" DestinationFiles="$(OutDir)ServiceConfiguration.cscfg" />
  <Copy SourceFiles="ServiceDefinition.csdef.tmp" DestinationFiles="ServiceDefinition.build.csdef" />
</Target>

Listing 1

As you can see in line 31 of listing 1, the ServiceDefinition.csdef.tmp (holds transformed xml) is copied to ServiceDefinition.build.csdef. CSPack knew about the convention that the .build.csdef file needed to be used to create the package. The package than can be deployed to Azure.

When we started to use the 1.8 sdk this did not work anymore. I found the following stack overflow post describing a change in this process, but not my issue.
After a lot of reading log files and studying .target files, I came to the conclusion that the convention using .build.csdef  does not function anymore, instead I tried changing the DestinationFiles atrribute value to “$(OutDir)/ServiceDefinition.csdef”. That works!

Mind the / after $(OutDir), if you do not use it the filename will be longer.
So line 31 will be:

<Copy SourceFiles="ServiceDefinition.csdef.tmp" DestinationFiles="$(OutDir)\ServiceDefinition.csdef" />

Listing 2

Henry Cordes
My thoughts exactly…