How can I avoid this deep folder structure with MSDeploy to filesystem using MSBuild?
Asked Answered
C

3

27

I'm pulling my hair out over this MSBuild issue.

We're using TeamCity to build a solution with two MVC websites in it. As part of the build we're deploying to a folder on the build server. IIS points to this folder to give us an integration build visible to management.

Here's the code from the MSBuild file that uses MSDeploy to publish a package - but not as a zip file.

<Target Name="Deploy">
  <MSBuild 
    Projects="$(SolutionFile)"
    Properties="Platform=$(Platform);Configuration=$(Configuration);
    DeployOnBuild=true;
    DeployTarget=Package;
    PackageLocation=$(PackageLocation);
    PackageAsSingleFile=False;
    AutoParameterizationWebConfigConnectionStrings=False" />
</Target>

The problem here is that we get an incredibly deep folder structure. Here's an example...

C:[ANYFOLDERS]\obj\Release\Package\PackageTmp[published files]

I really want to deploy to predictable folders like...

C:\build\website[published files] C:\build\mobilewebsite[published files]

That's the background. Here are the specific questions.

  1. Are we making a mistake trying to use MSDeploy to publish to a local filesystem? We basically need the equivalent of the VS2010 "publish" feature, with config transforms. We're not trying to deploy to remote IIS instances or anything.

  2. Is there any way of doing this but specifying the publish folders?

  3. I've been trying to use the MSBuild Copy task to copy the files into more sensible folders - but I can't work out how to use wildcards to specify the folders we need to take - it would need to be something like...

C:\FolderPackageEndsUpIn[ANYFOLDERS]\Website[ANYFOLDERS]\PackageTmp**.

Help!

Cid answered 16/11, 2010 at 11:50 Comment(1)
How do I achieve this in Azure CD pipeline?Meares
S
4

You can use WebDeploy directly to get a more tuned outcome. For example you can use the following command to sync 2 folders directly root-to-root:

>"%ProgramFiles%\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:dirPath=<SourceFolder> -dest:dirPath=<DestinationFolder>

Or you can make WebDeploy include IIS configuration on the destination by using iisApp provider instead of dirPath:

>"%ProgramFiles%\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:iisApp=<SourceFolderOrIISPath> -dest:iisApp=<DestinationFolderOrIISPath>

For example, to sync from a simple folder to a new app "NewApp" under Default Web Site, you will call it this way:

>"%ProgramFiles%\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:iisApp="d:\MyWebSite" -dest:iisApp="Default Web Site/NewApp"

Then, you can have a batch file that will perform sync/packaging by calling WebDeploy directly and will be execute as a post-build event.

Stringhalt answered 17/11, 2010 at 19:41 Comment(2)
I was doing it like this until I figured out that I couldn't get Web.config transforms to work. Any idea on how to do that without using the Package target?Quintie
You can solve this problem of Web.config transforms by crafting a skip replace rule that would make web deploy skip syncing web.config and replace web.release.config with web.config. Here is a blog post on skip replace rules to get you started: blogs.iis.net/msdeploy/archive/2008/05/23/…Stringhalt
P
33

If you add the _PackageTempDir parameter to MSBuild it will give you the same results as doing a local publish. e.g.

msbuild C:\PathToMyProj.csproj /p:Configuration=UAT;DeployOnBuild=true;PackageAsSingleFile=False;DeployTarget=Package;_PackageTempDir=c:\PathToMyDeploy\;AutoParameterizationWebConfigConnectionStrings=false

This command will publish all my files to c:\PathToMyDeploy\ without the crazy subfolders

Plait answered 9/7, 2012 at 4:37 Comment(1)
Thanks for that answer - that solved the problem for me. I use an azure pipeline to build my solution and was always anoyed by the deep folder structure.Hoarfrost
S
4

You can use WebDeploy directly to get a more tuned outcome. For example you can use the following command to sync 2 folders directly root-to-root:

>"%ProgramFiles%\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:dirPath=<SourceFolder> -dest:dirPath=<DestinationFolder>

Or you can make WebDeploy include IIS configuration on the destination by using iisApp provider instead of dirPath:

>"%ProgramFiles%\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:iisApp=<SourceFolderOrIISPath> -dest:iisApp=<DestinationFolderOrIISPath>

For example, to sync from a simple folder to a new app "NewApp" under Default Web Site, you will call it this way:

>"%ProgramFiles%\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:iisApp="d:\MyWebSite" -dest:iisApp="Default Web Site/NewApp"

Then, you can have a batch file that will perform sync/packaging by calling WebDeploy directly and will be execute as a post-build event.

Stringhalt answered 17/11, 2010 at 19:41 Comment(2)
I was doing it like this until I figured out that I couldn't get Web.config transforms to work. Any idea on how to do that without using the Package target?Quintie
You can solve this problem of Web.config transforms by crafting a skip replace rule that would make web deploy skip syncing web.config and replace web.release.config with web.config. Here is a blog post on skip replace rules to get you started: blogs.iis.net/msdeploy/archive/2008/05/23/…Stringhalt
B
4

There is a slightly hidden but elegant solution.

When running a build on a shared CI server it might be hard to pack in the c: root for isolation reasons. One would ultimately prefer to remove the deep path in the package itself.

Fortunately there is a solution. Add a replace rule in the .pubxml file! I found it in the supplement to inside ms build engine, 2nd edition: https://www.microsoft.com/learning/en-us/book.aspx?ID=16854

I also found it in this blog: http://learnaspmvc.blogspot.se/2014/07/web-packaging-fixing-long-path-issue.html

Becquerel answered 19/2, 2015 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.