VS2013 Publish using WebDeploy isn't transforming additional files - asp.net

I've build simple WebAPI project and not i'm trying to publish it using Visual Studio 2013 build in Publish mechanism (BUILD>Publish)
I've pick Web Deploy as publish method, got everything working, except transform files.
I have Web.config and Settings.config and two transforms for each.
When I do standard build on my project inside bin folder I see single Web.config and Settings.config with transform applied, but when I do publish instead of transformed Settings.config file I see one without transforms applied.
I't looks like publish mechanism inside Visual Studio is only transforming Web.config and it skips additional files.
Below is part of my csproj that is responsible for applying transforms:
<Target Name="AfterBuild">
<TransformXml Condition="Exists('Settings.$(Configuration).config')" Source="Settings.config" Destination="$(OutputPath)Settings.config" Transform="Settings.$(Configuration).config" />
<TransformXml Condition="Exists('Web.$(Configuration).config')" Source="Web.config" Destination="$(OutputPath)Web.config" Transform="Web.$(Configuration).config" />
</Target>
My question is how should I setup my publish profile so instead of copying clean Settings.config it will apply correct transform and publish it.
EDIT:
I've managed to find one thing that might help solving this. If I add UseMsdeployExe to pubxml I can see in Output that my Settings.config is transformed and saved to bin folder, but then later is it overridden by original file.
my AfterBuild target is called correctly, but after it I can see in output those lines:
2> Copying all files to temporary location below for package/publish:
2>obj\Debug\Package\PackageTmp.
2> Copying bin\Api.dll to obj\Debug\Package\PackageTmp\bin\Api.dll.
2> Copying Settings.config to obj\Debug\Package\PackageTmp\Settings.config.

Use SlowCheetah to transform the files, it will handle the deployment for you.
https://www.nuget.org/packages/SlowCheetah

Related

Removing comments from web.config on build

Is it possible to remove the commented lines from a web.config on build?
xml transform is fine to remove some elements but I couldn't find any syntax to clean the comments from the file.
We are using TFS 2010 build server for our builds.
<add xdt:Transform="RemoveAll" xdt:Locator="XPath(//comment())" />
Put this node within the root node of your transform file. "XPath(//comment())" selects all XML comment nodes to delete.
UPDATE: See actual and working answer below.
It's not possible to do with xml transformation.
But you can do it with your own console app or msbuild task.
See example code here Remove XML comments using Visual Studio 2010 Web Config Transformation
I had a similar problem where I wanted to remove dev comments from the config files before I published to the web site. I wrote an app that will recursively remove comments from config files in the directory I specify on the command line. The sample below assumes YourCommentRemover will do the same.
I included the comment remover project as part of my solution and referenced it in the web app I plan to deploy. You can just add the executable as a reference if you want. Since I didn't want the comment remover to get deployed, I added a task to delete it from the bin directory where it was being staged for deploy, (ProjectDir)obj\$(Configuration)\Package\PackageTmp\.
Open your project file in a text editor (You can right-click on the project file in the solution explorer and select 'Edit Project File').
Go to the very end of the project file and insert the following before </Project>:
<Target Name="BeforePublish" BeforeTargets="MSDeployPublish">
<Exec Command="$(ProjectDir)bin\YourCommentRemover $(ProjectDir)obj\$(Configuration)\Package\PackageTmp" />
<Exec Command="del $(ProjectDir)obj\$(Configuration)\Package\PackageTmp\bin\YourCommentRemover.*" />
</Target>
This target will run before any files are copied to the web application location on publish.

Publish web package adding tasks to copy files

I have an ASP.NET web package deployment using Visual Studios 2012 in which I would like to copy off files before deployment and then copy them back once deployment is completed. These files happen to be under Content\upload. If I just deploy.cmd the files are deleted and so currently I need to copy them off manually and then copy them back once deployment is complete. I have tried several examples of similar situations for adding tasks to the Project file as well as extra files added to the project, such as:
Adding tasks inside targets I have created called Name="BeforePublish" Name="AfterPublish" in the Project file.
<Target Name="BeforePublish">
<Message Text="BeforePublish"/>
<Copy/>
</Target>
Adding file called ProjectName.wpp.targets and adding
<Project>
<Target Name="CopyMyFiles" BeforeTargets="BeforePublish">
<Message Text="CopyMyFiles called"/>
<Copy/>
</Target>
</Project>
Neither of these techniques seem to be called. Any other ideas? Where and how should I put these tasks?
You can actually solve this using a skip rule. Try calling your command file like this:
deploy.cmd -skip:objectName=dirPath,absolutePath=Content\\uploads$
For more information on the skip directive, see Web Deploy Operation Settings.

Specifying folders not to sync in Web Deploy

I use the following script to deploy my ASP.NET MVC app to our web server:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MySolution.sln^
/p:Configuration=TeamCity-Test^
/p:OutputPath=bin^
/p:DeployOnBuild=True^
/p:DeployTarget=MSDeployPublish^
/p:MsDeployServiceUrl=https://mywebserver.com:8172/msdeploy.axd^
/p:username=MyDomain\MyUser^
/p:password=MyPassword^
/p:AllowUntrustedCertificate=True^
/p:DeployIisAppPath=mywebsitename.com^
/p:MSDeployPublishMethod=WMSVC
Now I need to specify to not sync the /uploads folder. Can I specify that in this script? Thanks!
Clarification:
I have the Uploads folder in my project. I'd like for Web Deploy to create the folder. I do not want it to delete the folder/subfolders/files from my web server because it contains user-uploaded content.
Clarification #2:
I just found the SkipExtraFilesOnServer=True option. However, I don't want this to be global. I'd like to set it to a single folder.
UPDATE:
Apparently, what you really want is prevent web deploy from removing existing directory on the destination server, but still have the folder created in case it's not there. You can accomplish this as follows:
create YourWebProjectName.wpp.targets file next to you the project file with the following content:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<MsDeploySkipRules Include="SkipELMAHFolderFiles">
<SkipAction></SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\NameOfYourFolder\\.*</AbsolutePath>
<Apply>Destination</Apply>
<XPath></XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipELMAHFolderChildFolders">
<SkipAction></SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\NameOfYourFolder\\.*\\*</AbsolutePath>
<Apply>Destination</Apply>
<XPath></XPath>
</MsDeploySkipRules>
</ItemGroup>
</Project>
Change NameOfYourFolder and YourWebProjectName accordingly. This assumes, you have it in the root, I believe, you can use relative path if it's not the case.
The first MsDeploySkipRules entry tells webdeploy not to remove any files in Name_OfYourFolder.
The second MsDeploySkipRules tells webdeploy not to remove any child folders in Name_OfYourFolder.
Also, to have the folder created if it's not present on the destination server, you have to do the following:
include the folder into the project
add a dummy DeployemntPlaceholder.txt file into it and include it into the project as well
DeployemntPlaceholder.txt is required to tell MSBUild to add the folder into the package: empty folders are ignored.
I've tested this approach and it works fine when you run publish in the manner you've shown. I've used this answer to get the msbuild items syntaxt right. I believe, this is a MSBuild way to customize flags, passed to webdeploy by MSBuild Deployment Pipeline.
If you ran MSDeploy directly, you could use skip arguments in the following manner:
-skip:objectname='filePath',absolutepath='logs\\.*\\someNameToExclude\.txt'
UPDATE 2
You might also want to have ACL write permissions set on your \Uploads folder - there's a complete guide to do this: Setting Folder Permissions On Web Publish
Conserning the original question "Specifying folders not to sync in Web Deploy", the easiest way to do this is as follows:
You can create a publish profile and add the following lines:
<PropertyGroup>
<ExcludeFilesFromDeployment>
File1.aspx;File2.aspx
</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>
Folder1;Folder2
</ExcludeFoldersFromDeployment>
</PropertyGroup>
I've tested this approach for excluding files using publish profiles. An easy guide is here (scroll to Edit the .pubxml file to exclude robots.txt section).
You can also do this in .wpp.targets file or edit you csproj. See more information at Web Deployment FAQ for Visual Studio and ASP.NET

How To Run MSBuild scripts in .wixproj?

Im trying to learn to make a web installer using Windows Installer XML (WIX 3.5). I found this blog about using msbuild in .wixproj files to avoid the scenario where the installer ends up dropping the web project assemblies right in the root of the app instead of keeping them in the bin folder like they're supposed to be.
Here is the link to that:
<http://www.paraesthesia.com/archive/2010/07/30/how-to-consume-msdeploy-staged-web-site-output-in-a.aspx>
But after adding the MSBuild scripts in the .wixproj file, I don't know what to do anymore. According to the instruction after adding the MSBuild script:
"When that target runs, you'll see a .wxs file pop out in the .wixproj project folder. Add the generated .wxs to your .wixproj project so it knows to include it in the build."
I really don7t know what this means. How can I run the target? I tried to build it but there was no .wxs file generated in the .wixproj folder.
Am I missing something? Please help...
Assuming you have added the section from the tutorial:
<Target Name="BeforeBuild">
...
</Target>
The target will be run automatically when you build the project. The "BeforeBuild" target is one of the standard entry-points to add your own modifications to the build. The target will then generate a file (named [WebProjectName].wxs that is placed in the same directory as your wixproj file. Click on the show all files button in visual studio and right-click on the file and "Include in project" That will then include the wxs is your installer and when you next build it will have the correct folder/file structure.

Make Web.config transformations work locally

I want to get web.config transformations working locally but apparently the transformations only occur when doing deployments.
Does anybody know of a way to run the msbuild target "TransformWebConfig" without it going through the "rebuild" process and also specify and output directory where to spit out the transformed web.config?
EDIT: Using Sayed's answer, I created a .bat file to do run the task for me:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Msbuild.exe "D:\Demo\Transformation.proj" /t:TransformWebConfig
copy /Y "D:\Demo\Web.config" "D:\MyProject\Web.config"
del ""D:\Demo\Web.config"
the "Transformation.proj" is a copy of Sayed's code snippet in the answer below. Just specify the source, target, and destination for the transformation. The new file, in this case, the transformed "web.config" will be in the "D:\Demo" directory. I am simply copying it over to overwrite my project's web.config and, finally, deleting the generated file in the "demo" folder.
Also, I created a macro to run this batch file and perform the tranformation for me:
Public Module DoTransform
Sub RunTransformBatchFile()
Try
Process.Start("D:\Demo\RunTransform.bat")
Catch ex As System.Exception
MsgBox(ex.Message)
End Try
End Sub
End Module
You can also add a button on your toolbar to run this batch and/or assign a shortcut key to execute.
if you want to transform a config file without using the Web Publishing Pipeline then you just use the TransformXml task manually. I've written a detailed blog post on this at http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx, but here are the high lights:
<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
<Target Name="Demo">
<TransformXml Source="app.config"
Transform="Transform.xml"
Destination="app.prod.config"/>
</Target>
</Project>
Here I manually transform the app.config file using transform.xml file and the destination file is app.prod.config.
One thing that you mentioned was being able to do transformation locally when running the app. The reason why we only perform the transform on package/publish is because if we transformed web.config itself then next time you debug your app the web.config gets transformed again. So for example if in your web.debug.config you have the transformation to add a value to config, everything is OK the first time you add that but then the next time your run/debug your app it will get added again. So it is best to avoid that.
If you are using Visual Studio 2015, you can just right click on the transform of the desired environment, and click "View Preview" ... It will then generate the transform, and you can copy and paste that into the normal Web.config file for debugging purposes. Just don't commit it!
If you are using Visual Studio 2013, you can install the SlowCheetah - XML Transforms extension

Resources