Search code examples
.netazuretfsmsbuildazure-web-roles

Create Azure package on TFS build


I want Azure Package files to be the output of a successful check-in build. We want to be able to publish these packages to Azure from a drop location.

According to this post, we only need the csdef file in order to create the package file using cspack in the command line:

cspack “c:\<path to the csdeffile>\servicedefinition.csdef” /role:<Name of the role as defined in the csdef file>;<location of the binaries> /sites:<Name of the role>;<name of the site path>;<location of the website files>

But I want to avoid using the command line. I know there is a CSPack task that can be used, but I have been struggling to find more information on it. I can't find any specification online, expect for some information on this Stackoverflow post.

How can I translate the above cspack command into the CSPack build task?

I have come up with the following based on the MSDN spec for cspack.exe but I have had to make a lot of assumptions:

<PropertyGroup>
  <VisualStudioVersion Condition=" '$(VisualStudioVersion)' == '' ">10.0</VisualStudioVersion>
  <CloudExtensionsDir Condition=" '$(CloudExtensionsDir)' == '' ">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Windows Azure Tools\2.2\</CloudExtensionsDir>
  <Roles></Roles>
</PropertyGroup>
<Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" />
<Target Name="CreatePackage" DependsOnTargets="Build">
  <CSPack 
      ServiceDefinitionFile="MyCloudProject\ServiceDefinition.csdef"
      Output="$(OutDir)Publish\$(ProjectName).cspkg"
      PackRoles="MyRoleName"
      SiteMapping="MyRoleName;MySiteName;MySitePath"
      RoleProperties="MyRoleName;$(OutDir)Publish\MyProject.dll"
      CopyOnly="false">
  </CSPack>
</Target>

I get the following build error:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Windows Azure Tools\2.2\Microsoft.WindowsAzure.targets (351): No default service configuration "ServiceConfiguration.cscfg" could be found in the project.

To be honest, I don't really know what I am doing. I have been at this for some time, so any guidance would be appreciated.

Copying the cspkg files will be easy enough, but I can't seem to figure out how to perform the packaging.

We are using Visual Studio Online (cloud-based TFS).

EDIT:

We do have cloud projects. This is how we have been publishing (right click -> Publish). This obviously isn't ideal as it doesn't follow a "Build Once" strategy and it adds further complications with a larger team.

@Simon Opelt: Would using the CorePublish target require a change to the build definition? Right now, the build definition uses a specific .build file (in order to perform a NuGet restore), which then runs the Build target for all projects in the solution:

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <OutDir>$(MSBuildThisFileDirectory)bin</OutDir>
    <Configuration>Release</Configuration>
    <ProjectProperties>OutDir=$(OutDir);Configuration=$(Configuration);</ProjectProperties>
  </PropertyGroup>
  <ItemGroup>
    <Solution Include="$(MSBuildThisFileDirectory)*.sln" />
  </ItemGroup>
  <Target Name="RestorePackages">
    <Exec Command="&quot;$(MSBuildThisFileDirectory).nuget\NuGet.exe&quot; restore &quot;%(Solution.Identity)&quot;" />
  </Target>
  <Target Name="Clean">
    <MSBuild Targets="Clean" Projects="@(Solution)" Properties="$(ProjectProperties)" />
  </Target>
  <Target Name="Build" DependsOnTargets="RestorePackages">
    <MSBuild Targets="Build" Projects="@(Solution)" Properties="$(ProjectProperties)" />
  </Target>
  <Target Name="Rebuild" DependsOnTargets="RestorePackages">
    <MSBuild Targets="Rebuild" Projects="@(Solution)" Properties="$(ProjectProperties)" />
  </Target>
</Project>

This also builds and runs our test projects. Would using the cloud project coupled with CorePublish still allow for this?


Solution

  • I could not get the CSPack task working. I ran into countless problems, so I went with executing cspack.exe directly:

    <PropertyGroup>
      <PackageCommand>
        "C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\v2.3\bin\cspack.exe" $(OutputPath)ServiceDefinition.csdef /role:MyRoleName;$(OutputPath) /sites:MyRoleName;MySiteName;$(OutputPath) /rolePropertiesFile:MyRoleName;$(OutputPath)RoleProperties.txt /out:$(OutputPath)Publish\MyRoleName.cspkg /useCtpPackageFormat
      </PackageCommand>
    </PropertyGroup>
    <Target Name="CreatePackage" DependsOnTargets="Build" AfterTargets="Build">
      <MakeDir Directories="$(OutputPath)Publish"></MakeDir>
      <Message Text="Using cspack create a package for deployment..."></Message>
      <Exec Command="$(PackageCommand)"></Exec>
    </Target>