- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Sunday, January 13, 2013

Web packaging fixing the long path issue

Someone sent me an email the other day to discuss some issues with the web packing experience in Visual Studio. One of his concerns were the directory structure in the .zip file that VS generates. If you are not familiar with this I’ll give you a quick overview. In Visual Studio 2012 when you create a web deploy package you typically end up with the full directory structure of your source inside the package. For example I have a project named WebApplication1 located at c:\temp\package\, when I create a package it contains the following files.

archive.xml
Content\C_C\Temp\package\WebApplication1\obj\Release\Package\PackageTmp
Content\C_C\Temp\package\WebApplication1\obj\Release\Package\PackageTmp\bin
Content\C_C\Temp\package\WebApplication1\obj\Release\Package\PackageTmp\bin\WebApplication1.dll
Content\C_C\Temp\package\WebApplication1\obj\Release\Package\PackageTmp\index.html
Content\C_C\Temp\package\WebApplication1\obj\Release\Package\PackageTmp\Web.config
parameters.xml
systemInfo.xml
 

These paths can get pretty long depending on where you keep your source. This has been one of my pet peeves as well.

I decided to take a closer look at this and I have a solution. 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.

The best way to solve the issue here is to update the package process to include a replace rule. This replace rule will update the full path into a simple path. We already have this concept baked into our Web Publish Pipeline. The replace rule that we would like to create will replace the paths C:\Temp\package\WebApplication1\obj\Release\Package\PackageTmp with website. Here is how to do it.

Edit the .pubxml file for the profile and add the following before the closing </Project> tag.

<PropertyGroup>
  <PackagePath Condition=" '$(PackagePath)'=='' ">website</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>

 

Let me break this down a bit. You 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. The replace rule added is equivalent to the command line switch shown below.

-replace:match='C:\\Temp\\package\\WebApplication1\\obj\\Release\\Package\\PackageTmp',replace='website'

Now when I create a package the contents are.

archive.xml
Content\website
Content\website\bin
Content\website\bin\WebApplication1.dll
Content\website\index.html
Content\website\Web.config
parameters.xml
systemInfo.xml

That's a lot better! If you try this out let me know if you have any issues.

 

Sayed Ibrahim Hashimi | @SayedIHashimi

Sunday, January 13, 2013 1:37:29 AM (GMT Standard Time, UTC+00:00)  #     | 
Sunday, January 06, 2013

Command line web project publishing

With the release of VS2012 we have improved the command line publish experience. We’ve also made all the web publish related features available for VS2010 users in the Azure SDK.

The easies way to publish a project from the command line is to create a publish profile in VS and then use that. To create a publish profile in Visual Studio right click on the web project and select Publish. After that it will walk you though creating a publish profile. VS Web publish profile support the following publish methods.

Command line publishing is only supported for Web Deploy, Web Deploy Package, and File System. If you think we should support command line scenarios for other publish methods the best thing to do would be to create a suggestion at http://aspnet.uservoice.com. If there is enough interest we may work on that support.

Let’s first take a look at how you can publish a simple Web project from the command line. I have created a simple Web Forms project and want to publish that. I’ve created a profile named SayedProfile. In order to publish this project I will execute the following command.

msbuild MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=<profile-name> /p:Password=<insert-password> /p:VisualStudioVersion=11.0

In this command you can see that I have passed in these properties;

You may not have expected the VisualStudioVersion property here. This is a new property which was introduced with VS 2012. It is related to how VS 2010 and VS 2012 are able to share the same projects. Take a look at my previous blog post at http://sedodream.com/2012/08/19/VisualStudioProjectCompatabilityAndVisualStudioVersion.aspx. If you are building the project file, instead of the solution file then you should always set this property.

If you are publishing using the .sln file you can omit the VisualStudioVersion property. That property will be derived from the version of the solution file itself. Note that there is one big difference when publishing using the project or solution file. When you build an individual project the properties you pass in are given to that project alone. When you build from the command line using the solution file, the properties you have specified are passed to all the projects. So if you have multiple web projects in the same solution it would attempt to publish each of the web projects.

FYI in case you haven’t already heard I’m working on an update to my book. More info at msbuildbook.com

Sayed Ibrahim Hashimi | @SayedIHashimi

msbuild | MSBuild 4.0 | MSDeploy | web | Web Deployment Tool Sunday, January 06, 2013 2:56:37 AM (GMT Standard Time, UTC+00:00)  #     | 
Friday, January 04, 2013

SlowCheetah support for Azure Worker Roles

I have had a number of request to get SlowCheetah working for Azure Worker Roles. I think I have it working now. I have not yet released the support to the download page yet but after the support is verified I will update the release.

If you would like to try out a build which has support to transform app.config, as well as other XML files, for Azure Worker Roles you can find the VSIX at https://dl.dropbox.com/u/40134810/SlowCheetah/issue-44/SlowCheetah-issue-44.zip. After installing for worker role projects you can create XML transforms for app.config, and any other XML file. When you publish to azure, or create a package your files should be transformed.

More info on this on the following issues.

BTW if you are interested in my upcoming MSBuild book checkout msbuildbook.com

Sayed Ibrahim Hashimi @SayedIHashimi

azure | SlowCheetah Friday, January 04, 2013 8:14:45 AM (GMT Standard Time, UTC+00:00)  #     |