TFS 2015 Visual Studio Build - Package .zip not being created - visual-studio

I'm trying to build my solution and package up the web app into a web deploy (.zip) package to be deployed.
I've added the Visual Studio Build step with the following MSBuild Arguments:
/p:DeployOnBuild=True /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:PackageLocation="$(build.artifactstagingdirectory)\"
And I've set up the Copy and Publish Build Artifacts step to copy all .zip files to the drop folder.
The build completes successfully but nothing is copied to the drop folder because there are no .zip packages that get created.
So when I look on the TFS server, the only thing in the 'a' folder is an empty 'drop' folder. And in the 's' folder is the solution directory with a PrecompiledWeb folder in it. Not sure what that is but it doesn't look like the deployment package (and it's not a .zip).
Any ideas?

I have tried the same on VS2015 MVC web application using VSTS and TFS 2015.2.1 both. I had to do a slight change to the Build arguments in Visual Studio build. That is removing the trailing "\" in /p:PackageLocation="$(build.artifactstagingdirectory)\".
Here is the argument I passed to Visual studio build step
/p:DeployOnBuild=True /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:PackageLocation="$(build.artifactstagingdirectory)"
Then I used Copy and Published Build Artifacts (Deprecated in VSTS you should use Copy task and Publish task instead of this task) as shown below
This gives me output as below.

First suggest you manually remote in the build agent and build the project through MSBuild command line with arguments to see if the project builds properly.
This will narrow down the issue is related to the environment on your build agent or your build definition.
You should directly use /p:PackageLocation=$(build.stagingDirectory
Besides since you have multiple assemblies that are referenced in the web app. Please also double check dependencies that are building in the correct order or referenced correctly.

Make sure the ASP.NET development workload of Visual Studio is installed.
If DeployOnBuild is having no effect, you may need to install the ASP.NET Development "workload" with the VS setup tool.
There are specific .targets files that, if they don't exist, cause these parameters to be silently ignored. Installing this adds those .targets and the parameters become active, allowing the .zip to be created.
For me (VS 2017) the relevant target file (or one of them, anyway) that was missing but is needed is:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.targets
If it is missing, you'll need to install as above, and if it is there, then you have a different problem. ;)

Related

Azure pipeline: msbuild does not copy one DLL in _PublishedWebsites

I have a strange behavior with msbuild on my Azure Pipeline.
I'm using Azure Pipeline with Self-hosted Windows agents.
Configuration:
My Visual Studio .sln contains two C# projects:
WebService (Rest API)
Business layer
In addition, the Business layer has dependencies on 2 others projects.
Kernel.DataModel
Kernel.DataAccess
The Kernel.DataAcess layer is using the NuGet package "Microsoft.SqlServer.Types" (14.0.314.76)
The Reference "Microsoft.SqlServer.Types" in the project Kernel.DataAccess has "Copy Local = True". Therefore the DLL file should be copied in the output (release) directory.
The problem:
When I run the Azure Build pipeline, the file "Microsoft.SqlServer.Types.dll" is not copied in the "_PublishedWebsites" directory.
To convince myself, I decided to run the same Pipeline on another build machine by changing the Agent Pool. At my surprise the DLL was present in the "_PublishedWebsites" on the second build machine.
Furthermore, I decided to manually run the msbuild command on my local computer and the the DLL was also present in the "_PublishedWebsites...\bin" on my local machine.
Log files:
I also looked at log files on the Build machines and on my local computer.
First build machine -> The DLL file is simply not copied !
Second build machine -> The DLL file is copied from this location.
Copying file from "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.Types.dll" to "F:\AgentLatestBuild\A1\_work\28\b\_PublishedWebsites\ApiProject\bin\Microsoft.SqlServer.Types.dll".
Local machine ->
_CopyFilesMarkedCopyLocal:
Copying file from "C:\TFS\Repos\Src\Project\**packages**\Microsoft.SqlServer.Types.14.0.314.76\lib\net40\Microsoft.SqlServer.Types.dll" to "E:\tfs\build\Microsoft.SqlServer.Types.dll".
Copying file from "E:\tfs\build\Microsoft.SqlServer.Types.dll" to "E:\tfs\build\_PublishedWebsites\ApiProject\bin\Microsoft.SqlServer.Types.dll".
As you can see:
On the second build machine, msbuild is not using the NuGet packages folder but it's using "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.Types.dll"
On my local machine, the DLL is copied from the NuGet packages folder.
Here are my questions:
How msbuild.exe is selecting the source/location of the DLL ?
Is there a way to force msbuild to first use the NuGet packages instead of any others folders ?
I think msbuild should first look in the NuGet packages folder and if the DLL is not found, then it should try to find it from somewhere else. (C:\Program Files (x86), GAC, etc..)
Finally, do you have any idea why the "Microsoft.SqlServer.Types.dll" is not copied at all on the first build machine. The DLL is present in at least three locations. (ie: NuGet packages folder, C:\Program files\ and it is also in the GAC).
It looks like msbuild is lost in the dependency tracking and can't find the file or it won't copy it for some other reasons.
Thanks for your help.
Is it possible that your *.csproj is targetting the wrong HintPath?
Could you check if you have something like this:
<Reference Include="Microsoft.SqlServer.Types">
<HintPath>..\packages\Microsoft.SqlServer.Types.YOURVERSION\lib\net40\Microsoft.SqlServer.Types.dll</HintPath>
</Reference>
thanks

Azure DevOps Build Task: create a zip with contents identical to Visual Studio Publish

In Visual Studio, when we publish to a folder, that folder contains exactly what we need to deploy.
In Azure Pipeline, the Build Solution task produces a a bunch of (to us) unnecessary files plus a zip file (nice!). The zip contains the files we need, but buried in an crazy deep folder path:
\Content\D_C\a\1\s\src\MyProject\obj\Release\Package\PackageTmp\our-files.dll
What we would prefer is:
\our-files.dll
It also modifies connectionStrings in the web.config to support the deploy script it ships with. We don't need that script and that modification is a pain (which we disabled by adding<AutoParameterizationWebConfigConnectionStrings>false</...> to the .csproj file - yuck!)` .
We tried fussing with the parameters in the Build Solution step:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"
Changing DeployOnBuild to false caused the $(build.artifactsstagingdirectory) to be empty (causing the next step to deploy nothing)
Changing WebPublishMethod to FileSystem made no difference (try finding documentation on the allowed values!)
Changing PackageAsSingleFile to false did what one would expect - no zip, but the contents were still buried in that deep folder structure.
Our downstream script could open the manifest file, xpath out the deep path baked into the zip (does the path always start with d_C?), unzip and grab the contents from there - but what a pain and how unnecessary.
Is there a way to publish just a nice clean build - a zip with contents that directly unpacks to the same files as a plain-jane Publish from Visual Studio does?
In the Visual Studio Build step change "MSBuild Arguments" to
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\" /p:UseWPP_CopyWebApplication=true /p:OutDir="$(build.artifactstagingdirectory)"
The key thing is /p:OutDir="$(build.artifactstagingdirectory)" resolves the directory issue and /p:UseWPP_CopyWebApplication=true removes web.config.release and web.config.debug
Then update Publish Build Artifacts step "Path to publish" to
$(build.artifactstagingdirectory)\_PublishedWebsites

Different results with MsBuild and Visual Studio

I have a solution, which consists out of 2 projects: regular class library for .NET 4.5 + website (not web application) project.
When I build this solution with Visual Studio - all referenced assemblies from Nuget packages and local references are copied to bin folder of website project.
If I try to build solution with MsBuild - bin folder of website project does not receive any assemblies.
Website project is not selected to be built in VS configuration (which is reported by message in both cases)
Edit - here is additional explanation.
When I clone a project from git - bin folder of website contains only 4 assemblies already checked in:
If I will run msbuild command with /t:Build or /t:Rebuild and /p:Configuration=Release;Platform="Any CPU" - I'll receive just an output of postbuild event in my other project, included in solution:
However, if I execute build from VS (Ctrl + Shift + b) in Release/Debug config - bin have all required assemblies for running web application.
Edit 2: Link to example solution - https://github.com/akuryan/csharp-website-test
When one builds it with msbuild TestApp.sln /t:Rebuild /p:Configuration=Release;Platform="Any CPU" - this results in only Test.Core.* and LetsEncrypt.Umbraco.dll (initially checked in) found at ~\Test.Web\bin\ (where Test.Web is website project). If one builds TestApp.sln with VisualStudion 2015 (I suppose, 2013 and 2017 will be the same) - ~\Test.Web\bin\ gets whole amount of assemblies.
Different results with MsBuild and Visual Studio
That because the all dll.refresh file in bin folder alongside the binary file are ignored by .gitignore.
Since Web Site projects do not have any project file (.csproj) to put the assembly references, the *.dll.refresh files are used by MSBuild to understand the assembly references. The contents of the file is the relative path to the .dll via the packages folder for the solution. When you ignore all those .dll.refresh by .gitignore, MSBuild could not understand how to handle the dll files.
To test this, I created a website project, add a nuget package to it, then delete the dll files but keep the .dll.refresh files in the bin folder. Build the website project by MSBuild command line:
msbuild.exe TestWebsite.sln /t:Rebuild
After this command complete, the dll files are copy to the bin folder.
So build and package restore to work it looks like you need to keep the .dll.refresh files in the bin folder. You can remove the other binaries from your version control system.
Note: If you want to get those .dll.refresh back, you can use the command line in the Package Manager Console:
update-package -reinstall
Hope this helps.

Visual Studio Team Services Basic Build and Deploy

I am trying to get a very basic build and release process going using Visual Studio Team Services.
I have created a bare bones Build that uses all default steps and settings for "Visual Studio".
Looks as though my problem is that no files are being copied in the "Copy Files To" step. it's Contents field = **\bin\$(BuildConfiguration)** (by default)
My project isn't being built to a bin directory though so no files are found to copy.
How do I get my web application project via Team Services to package only required files to a location so team services can find and copy only those required to deploy?
I was missing the following "MSBuild arguments" in the MSBuild task which does the website packaging for me.
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\"

VSO Copy website static files and binaries (not C# files)

I am trying to set up continuous integration on my server using Visual Studio online.
Created a new agent pool.
Installed and configured a new build agent that I added to that agent pool.
Then I trigger a new build of my code to be handled in my agent pool.
I manage to build it but how to set up the task "Copy and publish build artifacts".
My goal here is to just copy the final website files e.g. binaries, images, cshtml, but NOT all files such c# files. Well sort of like the "Right-click > publish" operation in visual studio.
What value do I need to enter in "Copy root" field? (please see image below)
The documentation is located at: https://msdn.microsoft.com/en-us/Library/vs/alm/Build/scripts/variables
It all boils down to what the output path for your binaries is. If you're not overriding it via an MSBuild argument, $(Build.SourcesDirectory) with a value of **\bin\* will probably get you what you're after.
For a web application, make sure you're building with appropriate MSbuild arguments (something along the lines of /p:OutDir=$(build.stagingDirectory) /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true should do the trick). This will get you a _PublishedWebsites folder in $(Build.StagingDirectory).
Then all you need to do is publish Copy Root of $(Build.StagingDirectory) and Contents of **\_PublishedWebsites\*
Keep in mind that Publish Build Artifacts means publish build artifacts to VSTS or a file share, not deploy build artifacts to a web server

Resources