Prevent MVCBuildViews from deleting MSdeploy Package - asp.net

I am trying to build and deploy my MVC project in VSO. I have only two steps in my Build definition and you can se them below:
And here are my MSBuild Arguments:
/p:DeployOnBuild=true /p:PublishProfile=Project.TEST.pubxml /p:DesktopBuildPackageLocation="" /p:WebPublishPipelineProjectName=Project.TEST /p:AutoParameterizationWebConfigConnectionStrings=False
My issue here is that when every i try to build this definition i get an empty publish zip file. I found out it is because of i have set MVCBuildViewsto be true in my .csproj file. If the MvcBuildViews is set to true then the project will build the views from this target:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
I have tried to set the BaseIntermediateOutputPath to another location but this solveds nothing because the compiler deletes the package folder in both locations.
I can't seem to figure out what to do. is there a way to disable CleanupForBuildMvcViews because this is what seems to delete the package folder before building the views.

Try adding the following attribute to your target:
BeforeTargets="PipelineCollectFilesPhase"
I think you just need to compile the views sooner in the build process (before the files are pulled for packaging). Not sure exactly which Target you should run before but this one looks right to me.

Related

VS2013 Publish using WebDeploy isn't transforming additional files

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

How to configure build for build undependent projects

I have a web project (asp.net) and I have several modules which should building in folder of the main project.
I can't find information about it.
I would like just build the main project and all modules should build too, but they not dependent with the main project.
Well, there still would be some dependency involved. You can use MsBuild task to build your projects along with main project. There are several options on how to include msbuild script to your solution, here is one of possible ways that allows to change the list of modules without reloading the MainProject and without adding dependencies to it.
Let's say we have MainProject and 2 modules: ClassLibrary1 and ClassLibrary2. Create a BuildModules.csproj file like this:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="BuildModules" ToolsVersion="4.0">
<ItemGroup>
<ModuleProject Include="ClassLibrary1\ClassLibrary1.csproj"></ModuleProject>
<ModuleProject Include="ClassLibrary3\ClassLibrary3.csproj"></ModuleProject>
</ItemGroup>
<Target Name="BuildModules">
<MSBuild Projects="#(ModuleProject)" Properties="OutputPath=..\MainProject\Bin\Debug;Configuration=Debug;" ContinueOnError="true">
</MSBuild>
</Target>
</Project>
Now this is a concept only, so I've hardcoded the path to bin\debug folder. ContinueOnError is true so in case some error occurs, it doesn't affect on MainProject build process. Put this file in your solution root folder.
Now in MainProject properties on Build Events tab add the following Pre-build command:
call C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe $(SolutionDir)BuildModules.csproj
The path to msbuild.exe may vary.
Now each time you build, it would rebuild your assemblies and you can easily change the list of modules in your BuildModules.csproj file.
UPDATE 1:
TFS not deploying all files. I guess this is because of our hardcoded paths to msbuild and etc. Try moving Pre-build command to MainProject.csproj file, in BeforeBuild target:
<Target Name="BeforeBuild">
<MSBuild Projects="..\BuildModules.csproj" Properties="Configuration=Debug"/>
</Target>
I'm not sure about the path though, but should be like this. And remove Pre-build command from build.

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.

MSDeploy Package has Missing Files

I'm using MSBuild to build a web application project and adding parameters to create the package file. All of that is good. I get two folders in the _PublishedWebSites output:
AppName
AppName_Package
In the ApplicationName folder, the entire site is there and I can simply copy this folder over to the website and it will run.
In the Package folder I've got the expected 5 files:
AppName.deploy.cmd
AppName.-readme.txt
AppName.SetParameters.xml
AppName.SourceManifest.xml
AppName.zip
When deploying the package however, the web application dll (AppName.dll) is missing, as are a few other important referenced dependencies.
Inspecting the package itself does reveal that the files are in fact missing from the web applications bin directory.
This is very odd, considering the files are all in the root AppName folder, but not in the package found in AppName_Package folder.
The only MSDeploy related modification I've made is that I am overriding the CopyAllFilesToSingleFolderForPackageDependsOn target to copy in some handlers from a library project, and this all works nicely.
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\Libraries\CodeLibrary1\**\*.ashx" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>$(ProjectDir)%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
So, I'm not able to determine why the web application's DLL, and only a few other (referenced)DLLs are removed from the bin directory during the package creation process (but not all - maybe 3%).
Any ideas what I should be looking for in the log file?
EDIT: (Response to Sayed):
I truly appreciate you answering my post. Unfortunately I’m not sure we are on the same page. Like I said, I might not have explained my problem well enough to actually clue others in on exactly what my issue is. Let me try once more to clarify
Getting external files copied into my web application was not the problem. I understand that scanning over my post and seeing the all too common “CopyAllFilesToSingleFolderForPackageDependsOn” element set off a few red flags, alarms, bells and whisles. . It seems to be a common thing people are struggling with, and as you point out, there have been some issues with it being executed. That worked OK for me.
My problem has more to do with project referenced DLLs, AND most importantly the application DLL itself not being copied.
More tweaking around today has revealed something I was not aware of. For instance:
Kicking off a Build on TFS outputs a couple things:
The source from TFS is output to the Source Directory (SourceDir)
This only contains the output what is checked into TFS
This does not include project or file references, only what is committed in TFS
The output of the build is into two folders
Binaries (includes project and file references)
Sources (only what is included/committed in TFS)
Inside Binaries I find the _publishedWebsites folder, as well as all project and file references, while inside Sources there are just the files that are checked into TFS.
My problem, or confusion, was thinking that when I pass in the following parameters to MSBuild Arguments, it would take the output from the build (_PublishedWebsites) and use those files to create the package. It does not do that.
The actual process builds a package based on the files in the SOURCES folder. So, here is my dilemma/confusion, because I did not commit my application dll into source, it was not being included in the package, and therefore was not being sent off to the test site on the test server.
/p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True /p:MSDeployPublishMethod=RemoteAgent /p:MSDeployServiceUrl=http://<mytestsite> /p:DeployIisAppPath="<AppName>" /p:UserName=<domain\user> /p:Password=<mypassword> /p:SkipExtraFilesOnServer=false /p:AllowUntrustedCertificate=True
To wrap this up, once I “checkout for edit” my application DLL on my dev machine, and them compile the solution, and finally commit the application DLL to source control, then it is included in the package because it is included as just another source item.
So, I guess this becomes my fault for not understanding how to get the output of the TFS BUILD into the sources folder, and get that included into the package used by msdeploy.
There is probably something very fundamental that I missed or just skimmed over - and not understood, that the package creation is from the Sources folder and not the _PublishedWebsites folder. Nor do I understand how to get the MSBuild compiled application dll, and project referenced dlls, into my package – replacing the committed source items in source control.
I hope this isn’t a complete waste of your time because I missed a
source=<some-parameter>
somewhere.
I appreciate it you can direct me to any existing sources out that already explain this to where I should be able to get my head around it and get this working. Or if it’s so easy to just tell me here.
The issue here is that the CopyAllFilesToSingleFolderForPackage target itself is not getting called from the VS2012 targets. We made a lot of changes and this may be a regression on our side. I will look into this to see if there is anything that we can do. Fortunately it should be pretty straight forward to update this to get the behavior that you are looking for. Instead of using CopyAllFilesToSingleFolderForPackageDependsOn you should be able to use PipelineCollectFilesPhaseDependsOn as an alternative. You should be able to change what you have above to
<PropertyGroup>
<PipelineCollectFilesPhaseDependsOn>
CustomCollectFiles;
$(PipelineCollectFilesPhaseDependsOn);
</PipelineCollectFilesPhaseDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<Message Text="Inside of CustomCollectFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles Include="C:\Temp\_NET\WAP-AfterPublish\MvcApplication1\additional files\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>additional files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
I just tried this for both VS2012 as well as VS2010 so this seems like a better to solution then the CopyAllFilesToSingleFolderForPackageDependsOn approach. Can you try that out and let me know what you find out?

AspNetCompiler including files that are not in my project

I'm using msbuild to automatically build and package a website ready for deployment. When I compile and then Publish my project through Visual Studio 2008 everything works fine.
However when I use msbuild I'm getting errors because AspNetCompiler is trying to compile aspx and ascx files that are not included in my .csproj, but still exist in version control.
I know I can just remove them from version control, but can anyone tell me why these files are being compiled?
Here is my msbuild task.
<AspNetCompiler
TargetPath="$(PackageDir)\Web"
VirtualPath="/"
PhysicalPath="$(buildDirectory)\Web"
Force="true"
/>
Thanks!
The AspNetCompiler task, which wraps _aspnet_compiler.exe_, compiles all "compilable" files in the application, rather than compiling only those files in the .csproj.
The giveaway is that none of the command-line parameters for the executable take a .csproj as input, only paths. (I suppose one could argue that it would look for a .csproj in the directory, but that is unlikely as it would introduce its own set of issues, such as what to do if someone had put two project files in one directory.)

Resources