WebAPI project doesn't seem to post transformed web.config to bin folder? - msbuild

I've bene doing well with .NET config transforms. I have them in place now on a class library for data usage and a WPF app.
However, when I attempt to set them up with an ASP.NET WebAPI project, something strange seems to happen.
The config file never shows up in my bin directory, and so the web.config always shows as the pre-formed config file.
If I run MSbuild with parameters of "/t:TransformWebConfig /pConfiguration=Test" on the csproj, I see the following:
CollectWebConfigsToTransform: Found The following for Config
tranformation: Areas\HelpPage\Views\Web.config, Web.config,
Views\Web.config, bin\Web.config PreTransformWebConfig: Skip copying
Web.config to obj\Test\TransformWebConfig\original\Web.config, File
obj\Test\TransformWebConfig\original\Web.config is up to date Skip
copying C:\Users\killesj1\Repositories\MRP Trunk\Macro
Projects\VEUploader\src\app\VEUploader.WebAPI\Web.config to
obj\Test\TransformWebConfig\original\bin\Web.config, File
obj\Test\TransformWebConfig\original\bin\Web. config is up to date
TransformWebConfigCore: Skipping target "TransformWebConfigCore"
because all output files are up-to-date with respect to the input
files. TransformWebConfigCore: Skipping target
"TransformWebConfigCore" because all output files are up-to-date with
respect to the input files. PostTransformWebConfig: Transformed
Web.config using Web.Test.config into
obj\Test\TransformWebConfig\transformed\Web.config. Transformed
C:\Users\killesj1\Repositories\MRP Trunk\Macro
Projects\VEUploader\src\app\VEUploader.WebAPI\Web.config using
C:\Users\killesj1\Repositories\MRP Trunk\Macro
Projects\VEUploader\src\app\VEUploader.WebAPI\Web.Test .config into
obj\Test\TransformWebConfig\transformed\bin\Web.config.
It appears that the transformation is tranforming the file, but somehow it's not making its way back into the bin directory, where the old Web.config remains.
Is this normal? How might I get this to behave similarly to other web transforms?

I had a similar problem, deploying Test projects on Appveyor that weren't being transformed, and followed the advice in the link below and now everything works nicely. I had all my projects set up to do xxx.config transforms in the [Target Name="AfterBuild"] and it worked perfectly on my local dev machine, but on pushing the code to Appveyor, the tests would fail because of untransformed files etc. Basically, move everything to the [Target Name="BeforeBuild"] and see if that helps.
MSBuild - how to force "AfterBuild" target when I do deployment?

web.config normally located in the root and is not copied to bin subfolder. To apply transforms you need to have some template web.config and transform it to root web.config.
E.g. see https://stackoverflow.com/a/16239488/52277 and Use Visual Studio web.config transform for debugging

Related

Is it possible for csproj/msbuild to include files as optional content?

I have an optional config file in my application that is used for instance-specific configuration. The application works without it, and it is only necessary if you want to configure some additional features. It therefore shouldn't get included in the source control as every developer and client deployment doesn't need it and those who do will have different values.
I have a problem figuring out how to configure this for continuous deployment. I can generate the file on the build server without issues. However, since MsDeploy reads the csproj to determine which files to deploy, this file has to be tracked by my csproj to actually be moved to the deploy server. But if I have it tracked by my csproj, then it becomes no longer optional and I can't build the application without it. I'm using Mercurial which doesn't have a commit-one-version-ignore-subsequent feature (git's --assume-unchanged) so options seem pretty limited on that front. I am a very strong believer that it should be possible to clone a repo and run the project immediately, so I really don't like the idea of comitting something that cannot build.
Is there a way in the csproj file to indicate that a file should be included as content if present and ignored otherwise?
If this is the only .config file in the directory, then you can edit .csproj file manually to reference your file via file mask:
<ItemGroup>
<Compile Include="*.config"/>
</ItemGroup>

Exclude folder when building from VSO to Azure website

I am trying to exclude certain files/folders from deployment of a web project in Visual Studio Online to an Azure website.
The web project has a Content folder with CSS, JS, build scripts and so on, which are only necessary for development, once deployed to Azure the CSS and JS is loaded from a CDN. Currently the build from VSO is copying all those files to the webroot in Azure, which is unnecessary and a potential security issue in case of the build scripts.
Now I know this can be prevented by setting the build action of a file to None, but this a very tedious solution because there is a lot of development going on, new files get added all the time and it is easy to forget this setting.
First I tried setting the Content folder to Cloaked in the build definitions source settings, but this only causes VSO to not download this folder on build, msbuild will still complain that those files are missing.
Is there a way to tell msbuild to ignore the whole Content folder? I already tried adding /p:ExcludeFoldersFromDeployment="Content" as a msbuild argument in the build definition, and also tried the solutions in here How to get Visual Studio 'Publish' functionality to include files from post build event?, but nothing is working.
I was studying msbuild log files and came up with a solution that is good enough for us to work with.
The first thing I learned was that I cannot prevent msbuild from copying files with build action Content to the output directory, at least not without changing the Microsoft.WebApplication.targets file, which I didn't want to do and am not even sure is possible with VSO build.
Anyway because of this we cannot set the source settings of our Content folder to Cloaked in the build definition, since this will cause the build to fail.
What we ended up doing was described in this answer: https://stackoverflow.com/a/3140349/1230302
So by adding the ExcludeFoldersFromDeployment statement to the .csproj file, the Content folder is excluded from the webroot.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\</OutputPath>
<ExcludeFoldersFromDeployment>Content</ExcludeFoldersFromDeployment>
</PropertyGroup>
It is not an ideal solution, but at least this way nothing gets deployed if a developer forgets to set the build action to None.
The built in continuous delivery options are designed for convenience. Of you need something custom, like skipping deployment of files that have not changed, then you will need to write something yourself.
You can easily call PowerShell to complete any task from the build process.
If you'd like to customize your build as part of the VSO build system, you can just override your BuildTemplate.xaml file.
Visual Studio Build uses Windows Workflow (xaml) to make a workflow on what the build is supposed to do. You can edit this file and do any modifications to the directory structure before or after the build.
Here is an example.

TFS Build dropping extra files including csproj in target folder

I have an automated build process set up to run from a build definition in TFS, which publishes a web application and generates/executes a database project script successfully via publish profiles that are passed as msbuild arguments in the build process definition. Everything is now running as expected except that several unnecessary files are being deployed to the target folder, including the .csproj file, all of the config transforms, and the properties folder which contains all of my publish profiles.
This is strange because 1. It's definitely not including ALL files/folders and mostly appears to be including ones used by the publish profile like transforms, while applying the transform correctly and excluding any explicitly excluded file (as defined in the pubxml), and 2. The process works perfectly if I do it by publishing from the project in Visual Studio 2013. I have the profile configured to only include files needed by the application, and I've confirmed in the csproj file that this property is there.
I tried excluding the properties folder from deployment in the pubxml file, but this causes the build to crash because it can't find the assembly file. What I've gathered is that the process is keeping all files it needs to complete the build, and dropping all of those files in my destination folder. FWIW, I'm using the "file system" method and I'm not sure yet if web deploy will make a difference. I haven't been able yet to connect to the target server with web deploy, but that's a separate problem to solve. Is there something in the build that I can configure so that my destination folder has only the files it needs to run the application, and not the files needed to BUILD the application?
FYI I also have not been using a drop folder, I'm not sure if that makes a difference or not but that might be the only thing I haven't tested as it doesn't seem necessary since I'm using a publishprofile and don't want to use the default tfs build configuration.
I found a solution that works well enough, after reading this: http://www.asp.net/web-forms/tutorials/deployment/advanced-enterprise-web-deployment/excluding-files-and-folders-from-deployment
This was a little uglier solution than I wanted, since it requires hard-coding the names of excluded files, but it does the trick and only requires identifying the files and folders in one location instead of altering a publish profile for each target environment. I created a wpp.targets file and used the ExcludeFromPackageFolders and ExcludeFromPackageFiles elements to identify the extra files. Ironically, if I don't also name the wpp.targets file in the exclude element, THAT file is included in my package. It's possible MSDeploy doesn't have the same issues with TFS as filesystem, but after spending half a day trying to work through a different set of issues and permissions workarounds, we decided that file system is a cleaner publishing method.

TFS Build: Files being packaged for certain configurations but not others

When we use TFS Team Build to compile and create deployment packages for each of the configurations for a project (Dev, Test, UAT, Live) (to get a necessary transformed web.config for each environement).
In order to include files outside of the project into the deployment package we have added something like the following in csproj file:
<Content Include="FilesToIncludeFolder\**\*" />
This works for all but one of the configurations. Ie the files get included in all but one of the packages.
The only difference between a configuration for which it works and one that it doesn't is its name and the fact we have a different web.config transform for each. Any ideas why this is happening?
In the log file created by msbuild the configuration that acts correctly has our files listed under this section
CollectFilesFromContent:
Gather all files from Project items #(Content). Adding:
When it doesn't work they aren't. It seems like the files within #Content become different for different configurations. Why should this be, there is nothing in our build process or csproj file that treats them differently and its the same csproj file in each case?

How to specify MSDeploy parameters from MSbuild

I have a web application that I am trying to deploy and have the web.config file parametrised.
I can build the package by running
msbuild myproj.csproj /T:package
now when it produces the package, i get a file in the directory.
Archive.SetParameters.Xml
This file has Parameters in it that if I change they would end up in the deployed package. My Question is, how can i define more parameters so that when I build the project it has my extra parameters in the file.
I belive i could do it using MSDeploy -declareParam But how would I do this from MSBuild? or the .csproj file.
My end goal is to have a parametrised Web.config file for deployment into multiple environments.
Ok so turns out this is fairly easy, after some significant googling eventually found this post
http://vishaljoshi.blogspot.com/2010/07/web-deploy-parameterization-in-action.html
VS 2010 makes your life easier by allowing you to simply drop the
Parameters file in the root of your web project and if a file with the
name Parameters.xml is found in the root of your project it passes it
to Web Deploy which then parameterizes your web…