Deployed dll file is not the one built by TFS - tfs

I have a TFS 2013 build definition that recently started to act strange. Its been doing its job for over a year now without any problems.
It builds 4 different projects. Two of them are asp.net mvc/webapi projects which also are deployed via msdeploy to two separate websites on the same QA staging web server. The build is configured to use Release|Any CPU
When the build runs the dll version is set using the ApplyVersionToAssemblys powershell script.
In the build folder all the assemblies have the correct version. But in one of the deployed web sites one of the dll files "WebUI.dll" has version number 1.0.0.0 ie not the same as the same dll in build directory has which is 4.0.buildnumber
The deployed "WebUI.dll" also seems to be built in Debug mode becuase some buttons and actions are only displayed when DEBUG is defined.
If I copy the built WebUI.dll from build directory or even the PublishedWebsites directory everything works as expected.
So my question is how can MSDeploy via MSBuild create its "own" version of the WebUI.dll? (And no - the Define DEBUG constant checkbox is not checked in Release mode). The version 1.0.0 WebUI.dll cant be found anywhere on the server so I guess it must be "created" when msdeploy runs?
(The only change I've made recently is to add a new build definition which builds the same solution and runs all tests but does not deploy anything.)
UPDATE: I tried to publish from VS using the same publish profile used by the build process and that works as expected. The WebUI.dll deployed is built in release mode. The version is not applied becuase that is part of the build process but the important thing is that its the Release mode dll that is deployed and not Debug which is the case when the buildprocess does the deploy. I also tried creating a web deploy package and installed that on the local server with the same result.
So the problem is still that the WebUI.dll built in the build process is correct (Release mode and correct versioning) - but gets "replaced" during the deploy on the build server by a Debug mode and without versoning
UPDATE 2; Msbuild cmd
C:\Program Files (x86)\MSBuild\12.0\bin\amd64\MSBuild.exe /nologo /noconsolelogger "C:\Builds\2\Products\SomeApp4.Main\src\SomeApp4\Main\Source\SomeApp4.Web.sln" /nr:False /fl /flp:"logfile=C:\Builds\2\Products\SomeApp4.Main\src\SomeApp4\Main\Source\SomeApp4.Web.log;encoding=Unicode;verbosity=normal" /p:SkipInvalidConfigurations=true /p:DeployOnBuild=true /p:PublishProfile=Chicago /p:AllowUntrustedCertificate=true /p:Password=bw /m /p:OutDir="C:\Builds\2\Products\SomeApp4.Main\bin\SomeApp4.Web\\" /p:Configuration="Release" /p:Platform="Any CPU" /p:VCBuildOverride="C:\Builds\2\Products\SomeApp4.Main\src\SomeApp4\Main\Source\SomeApp4.Web.sln.Any CPU.Release.vsprops" /dl:WorkflowCentralLogger,"C:\Program Files\Microsoft Team Foundation Server 12.0\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;BuildUri=vstfs:///Build/Build/740;IgnoreDuplicateProjects=False;InformationNodeId=14;TargetsNotLogged=GetNativeManifest,GetCopyToOutputDirectoryItems,GetTargetPath;LogProjectNodes=True;LogWarnings=True;TFSUrl=http://boston.SomeCompany.local:8080/tfs/SomeCompany;"*WorkflowForwardingLogger,"C:\Program Files\Microsoft Team Foundation Server 12.0\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;" /p:BuildId="abd7db3d-4ff8-43b4-ab36-f35c6f6e5697,vstfs:///Build/Build/740" /p:BuildLabel="SomeApp4.Main_4.0.6.740_20160121_103558" /p:BuildTimestamp="Thu, 21 Jan 2016 09:35:59 GMT" /p:BuildSourceVersion="LSomeApp4.Main_4.0.6.740_20160121_103558#$/Products" /p:BuildDefinition="SomeApp4.Main"

When you change the assembly version, the version under source control won't be changed. You can only change the version which has been copied on your build agent machine. If the source of the msdeploy command point to the project in TFS, you won't get the versioned assembly.

I found the problem.
The build definition builds 4 solutions where one is the WebUI(aspnet mvc) solution and one is an Api solution (asp.net WebApi)
In the Api solution a project was referencing the WebUI project but the WebUI project wasnt in the Api solution.
MSbuild resolved the WebUI project anyways so there were no errors and build + deploy of the api solution worked. But the WebUI project was built in debug mode since it has no solution configuration in Api solution I guess
The problem when msbuild ran the api solution with deploy flag it also managed to deploy the WebUI project built in debug.
So the WebUI project was deployed twice. First the correct one from the WebUI solution and then the wrong debug WebUI compiled with the Api solution.
Doh! Is all I have to say about that.
Thanks for your help guys.

Related

Azure DevOps PipeLine MSBuild does not produce web folder like local command

Fairly new to Azure DevOps and PipeLines, but we are stumped by the fact executing an MSBuild command locally or through publish in VS2019 gives us a complete ready to publish folder, while the same command in Azure DevOps pipeline seems to be doing nothing but build.
Local command:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild" Webshop\Mvc.csproj /p:PublishUrl="c:\Publish\Mvc" /p:DeployOnBuild=true /p:Configuration=Release /p:WebPublishMethod=FileSystem /p:DeployTarget=WebPublish /p:AutoParameterizationWebConfigConnectionStrings=false /p:SolutionDir="." /p:PrecompileBeforePublish=true
MSBuild task:
steps:
- task: MSBuild#1
displayName: 'Build solution'
inputs:
solution: '$/MVC_Projects/<more here>/Webshop/Mvc.csproj'
msbuildVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArguments: '/p:DeployOnBuild=true /p:DeployTarget=WebPublish /p:PublishUrl="$(build.artifactstagingdirectory)\publish" /p:WebPublishMethod=FileSystem /p:AutoParameterizationWebConfigConnectionStrings=false /p:PrecompileBeforePublish=true'
We tried playing with the parameters, but that does not seem to have much effect (or we don't know which parameters to tweek). The most we got was adding an /p:DeployTarget=Package and /p:OutDir="$(build.artifactstagingdirectory)\bin" would copy the bin folder. This was still without the .compiled files we were expecting though.
The project is an ASP.NET MVC Framework 4.8 application. The code does build properly and without errors. The logs do not hint with any warning or tasks not being able to be completed, so no clues there. We require the output folder for the full website and not just the DLL's to make our migration to DevOps easier. Having the folder allows other deployment processes to remain the same.
This might not be best practice, but it is practical for us at this moment in time.
Question 1. Why is MSBuild doing something else locally than in the DevOps Pipeline? Is it perhaps picking up configuration files we are unaware of ?
Question 2. What settings (or perhaps other task) would we need to set up to get the same local publish folder appear in the $(build.artifactstagingdirectory) folder in DevOps ?
Any insight, direction or solution is appreciated.
SOLUTION
After many checks and trials in the build parameters and pipeline setup, it was a DevOps server installation issue. The DevOps server had a full version of 2022 installed and only a partial version of 2019. Although the builds did not give any error or warning, the artifacts were not created without the 'ASP.NET and web components' for Visual Studio 2019 being installed. After that component was installed, the builds ran just fine and as expected.
Lesson learned is to double check local development installation with server installation with relation to installed (individual) components when results vary, even if there are no errors.

How do I get my Windows service solution to produce an artifact with VSTS Build?

I have a build definition in Visual Studio Team Services (a.k.a. Visual Studio Online? I'm not really sure the right name for it honestly) that is not producing an artifact, and I'm really not sure why. The main project in the solution file is a Windows service that is built using TopShelf. I suspect that maybe the MSBuild arguments in the Visual Studio Build task might be wrong. I copied them from a build definition for an MVC project that is working, but it occurs to me that they might not work for a Windows service.
Here they are:
/p:DeployOnBuild=true
/p:WebPublishMethod=Package
/p:PackageAsSingleFile=true
/p:SkipInvalidConfigurations=true
/p:PackageLocation="$(build.artifactstagingdirectory)\\"
I have a Copy Files task and a Publish Build Artifacts task later on in the process, but apparently the $(build.artifactstagingdirectory)\\ is empty. I get this warning:
##[warning]Directory 'd:\a\1\a' is empty. Nothing will be added to build artifact
Oddly enough, in another task in the process where I publish the symbols, everything appears to go off without a hitch.
One more bit: I'm using a hosted build agent. Not sure if that matters or not.
That's all of the pertinent information I can think to provide. Am I way off base here? I've used Octopus Deploy in the past and I know I had to install Octopack on my services. Do I need to do something similar here?
You don't need any of those MSbuild arguments; most of them apply to ASP .NET projects and will do nothing for a console application.
Replace them all with /p:OutDir=$(Build.ArtifactStagingDirectory). That will tell MSBuild to put the build outputs in the artifact staging directory.

Linked file in WCF RIA service does not build in TFS Build server

I've just setup a TFS (2012) server and now I'm trying to build the complete code (written in .NET 4.0 in VS 2010) via the TFS Build server. But in my solutions I have also a WCF RIA project which contains linked files because they are used somewhere else also and there is no possibility to add a reference to a general .NET binary in WCF/Silverlight.
Everything builds without any problem on my development machine but when I check it all in, create a standard build definition and run that build definition I get the following problem. The linked files have usings (UsingNamespace for example) to other projects that are also build by us and build before the WCF/Silverlight but the following error pops up while building through TFS Build server:
The type or namespace 'UsingNamespace' could not be found (are you
missing a using directive or an assembly reference?)'
Is there any solution for this problem that I looked over?
EDIT 1
Just tried to set the Copy to Output Directory propertie of the linked files to Copy Always but this still gives me the same error as I was expecting. The problem is that the linked file is placed somewhere that it can use the usings but the WCF RIA service cannot access/find that using.
EDIT 2
Just tried out my local test TFS where I can do what I want and there I made a build definition with just the solutions needed to make that the project with the linked files builds. This worked without any problem. Then I tried the same on our TFS server with a new build definition that has the same solutions as on my test TFS and here it did not work. The only difference that I know for sure is that my test TFS is TFS 2012 Update 1 and that my production TFS does not have the update 1 yet. I'll try to install it next week.
EDIT 3
I've just updated our production TFS to Update 1 but it is still not working with my temporary build definition which only contains the projects that are needed to build the silverlight application with the linked files. The 2 workspaces are the same on both server and the projects to build are also the same.
You need to specify the workspace information in the Build Definition for the build to use. The workspaces are what the build process copies from source control to the build server. If you don't have everything in the build server's workspace, it can't build properly.
The Source Control Folder in the workspace tab is the location of the files you need from TFS. The Build Agent Folder is a relative path from the build server's pre-defined base location. You'll usually use $(SourceDir)\Folder to specify the "Folder" that your build process needs.
This sounds like an $(Outdir) problem. A build definition in TFS automatically overrides the Bin folder. All Binaries are redirected to the bin folder upon compile. Sounds to me that you are using a mixture of project references and file references. The file references are probably what is causing your build failures.
Example if you compile in the same build the following solutions
Solution1.sln (TFS Build Pass)
project1.csproj
project2.csproj (references project 1)
Solution2.sln (TFS Build Failure)
project3.csproj (references binary output of project 1)
Expectations from TFS out of the box without customizing your workflow is that this simple build will fail. The reason is that in your development box all projects produce output to one destination while in a tfs build your projects will build to $(Outdir).
Some Things to try
Simple (best practice in my view)
Create 1 solution and use project references instead of file references.
Complex
Build using MSBuild project files
Modify your windows workflow to not override the $(Outdir)
Copy the binaries after a build is complete.
Best practice on Automating Builds
Build from command line
Build from cmd a NON vs2010 command line.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe FullpathtoSolutionFile.sln
Cheers!
Apparently there was just missing the WCF RIA services V1.0 SP2 on the TFS server. If that was installed the problem was solved.

Using Octopack on a TFS build with a website + windows service

I have a website, a windows service, and some shared class libraries in a single Visual Studio solution. I use Octopack on both the website and windows service, and on my machine these builds work as expected.
When using the TFS Build Server, the website nuget package is generated as expected, but the windows service nuget package contains all files from the website, as well as the service. E.g. it includes the _PublishedWebsites folder as well.
This is because TFS uses a single location to build projects.
What is the best way around this?
I know this question has since been closed, but I cam across this issue and solved it in a different way.
My solution is compromised of a number of websites and windows services and had the same issue of the OctoPack created nuget packages including all the solution assemblies from the 'pooled' output folder when building with Team Build. The reason the nuget packages get all the assemblies is OctoPack uses the outdir msbuild argument as the location to include assemblies from.
The way I got around it was to use the msbuild argument GenerateProjectSpecificOutputFolder=true. This instructs Team build to create a folder for each project in your output folder in the same way Visual Studio uses the bin folders under each project when building locally.
My build definition msbuild arguments looks like:
/p:GenerateProjectSpecificOutputFolder=true;RunOctoPack=true;OctoPackPublishPackageToFileShare=\\<NugetServer>
I currently just push the packages onto a shared folder but the OctoPackPublishPackageToHttp and OctoPackPublishApiKey parameters can also be used.
The benefit of this solution over the one above is you don't need to specify the files to include the nuget package.
Hope this helps someone.
I ended up using this nuget package to ensure the console app built to a seperate directory on the TFS server.
https://nuget.org/packages/PublishedApplications/2.1.0.0
I then had to specify in the nuspec file, which files should be included for the console app. e.g
This works and I can now deploy using Octopus deploy.
The downside of this apporach is that the PublishedApplications build only works on the TFS build server, so I can't build the project locally in release mode. Still looking on how to overcome this.

How to create web deployment package from team build?

I've been reading and experimenting for days. I bought the latest "Inside the Microsoft Build Engine - Using MSBUild and Team Foundation Build". I've been trying to figure things out by looking at the build targets.
I was quickly able to get a package to be built on the build server, but I want to be able to specify the installation folder, so it doesn't go into wwwroot. I read that I would have to switch the project over from using cassini to the local IIS server. Went through all of that.
The args I'm passing to msbuild through the definition:
/p:DeployOnBuild=true /p:DeployTarget=Package /p:MSDeployPublishMethod=InProc /p:CreatePackageOnPublish=True /p:MsDeployServiceUrl=localhost
I've got SO MANY questions, but I'll start simply. If anyone can provide guidance I'd be super thankful.
If the named application doesn't exist on the build server (which it shouldn't!) the package creation fails. If I add a shell app named accordingly the package is built.
Even if I hack my way past #1 when I try to deploy using Web.deploy.cmd, it fails:
Error: Using a 64-bit source and a 32-bit destination with provider appHostConfig is not supported.
Note that the build server is 64-bit and THIS target server (development) is 32-bit. I have the build configuration building against "any cpu". Oh, and I'm invoking the deployment FROM the 32-bit machine, so there's only the 32-bit msdeploy.exe available.
In the appropriate BuildDefinition under "Process", expand the "Advanced" section and set the value of "MSBuild Arguments" to "/p:DeployOnBuild=True".
That will make your WebDeploy Package built according to your settings in the project properties.
I write 2 articles about how to create Web Package and auto deploy it to a Web Server, I think it maybe useful for you.
Auto Deploy your Website for QA with Team Build click here
How to run remote deploy with MS Deploy? click here

Resources