2
votes

I have a Visual Studio solution that contains four projects:

1 Desktop app; 1 Windows Service; 2 Web API projects.

These projects have been migrated from VS2010 -> 2013 -> 2017. I've removed/edited as much legacy stuff as I recognise.

The solution builds fine in 2017.

I wish to only build one of the Web API projects, generate a deployment package, and publish the package as an artifact. A release definition is going to use WinRM to deploy the package on a Windows Server 2012 system running IIS.

In my build definition I have a MSBuild task.

The parameters of this task are as follows:

  1. Project is set to the path of my webAPI .csproj in TFS source control
  2. Platform is set to "AnyCPU" - ("Any CPU" doesn't work.. its a known (old) issue)
  3. Configuration is "Release"
  4. MSBuild arguments are:

/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation=$(Build.ArtifactStagingDirectory)\webapi.zip

  1. Clean is set to true

The build completes successfully, however the webapi.zip package that is produced contains a massive folder structure:

C:\agent2_work\27\a\webapi.zip\Content\C_C\agent2_work\27\s\MyProduct.WebApi\obj\release\Package\PackageTmp

Questions:

  1. Why is it packing this full path? (c:\agent2_work is my build agent's directory)
  2. How do I change it?
2

2 Answers

2
votes

It's the expected behavior, it's based on your Package Location. If you publish the project in VS, you will find the similar folder structure. See Create a Web Deployment Package in Visual Studio for details. And this thread for your reference.

However you can change the folder structure with publish profile used in MSBuild Arguments. Following below steps to do that:

1, Create a publish profile.

To create a web deploy package in VS you will first create a publish profile for that. When you do this, a .pubxml file will be created for you under Properties\PublishProfiles. This is your publish profile file, its an MSBuild file. You can customize your publish process by editing this file. We will modify this file in order to update these paths in the package.

2, Edit the .pubxml file for the profile and add the following before the closing </Project> tag. (Create the target AddReplaceRuleForAppPath, and inject that into the package process by adding it to PackageDependsOn property. Once this target is executed it will add a replace rule into the MSDeployReplaceRules item group.)

<PropertyGroup>
  <PackagePath Condition=" '$(PackagePath)'=='' ">WebApi</PackagePath>
  <EnableAddReplaceToUpdatePacakgePath Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='' ">true</EnableAddReplaceToUpdatePacakgePath>
  <PackageDependsOn>
    $(PackageDependsOn);
    AddReplaceRuleForAppPath;
    </PackageDependsOn>
</PropertyGroup>

<Target Name="AddReplaceRuleForAppPath" Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='true' ">
  <PropertyGroup>
    <_PkgPathFull>$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)))</_PkgPathFull>
  </PropertyGroup>

  <!-- escape the text into a regex -->
  <EscapeTextForRegularExpressions Text="$(_PkgPathFull)">
    <Output TaskParameter="Result" PropertyName="_PkgPathRegex" />
  </EscapeTextForRegularExpressions>

  <!-- add the replace rule to update the path -->
  <ItemGroup>
    <MsDeployReplaceRules Include="replaceFullPath">
      <Match>$(_PkgPathRegex)</Match>
      <Replace>$(PackagePath)</Replace>
    </MsDeployReplaceRules>
  </ItemGroup>
</Target>

3, Save the Publish Profile file and check in the changes

4, Enter below MSBuild arguments: (In this example my publish profile name is 1011DP.pubxml)

/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:PublishProfile=1011DP /p:SkipInvalidConfigurations=true /p:PackageLocation=$(Build.ArtifactStagingDirectory)  

5, Run the build, then check the folder structure.

enter image description here

0
votes

To make things a bit easier I just created a nuget package that performs these steps automatically for you. See https://www.nuget.org/packages/SharpSvn.ShortMSDeployWebContentPath

Just installing this in your web application project from Visual Studio will change the long path below 'Contents' with just the single word 'web'