Troubleshooting missing files and failed builds for your Visual Studio projects
As with any build server technology, when our build servers download your source code to compile it, a number of things can cause your build to fail. Troubleshooting the issue locally often allows you to find and apply a really simple fix, without having to do the “checkin, build, investigate” dance that can sometimes occur when using Continuous Integration.
Where did it all go wrong?
Whether you’re running a local build server environment or a service that manages your Continuous Deployment in the cloud like OnCheckin, it’s important to get a basic understanding for how build servers work.
When you take a look at our “What software is installed on a build server” page you’ll notice that there’s a bunch of stuff on each OnCheckin build server, including different versions of Visual Studio. If you ran your own local .Net build server, this statement would probably be the same.
While this might normally lead you investigate your failing builds in Visual Studio before running your next OnCheckin build, we normally advice against this.
Visual Studio compiles your project “in place”, meaning that it creates binaries in your project’s Bin folder, and then when you run your application in Visual Studio to debug it executes from within this same folder. This can cause a number of project misconfigurations to be hidden from view, until you commit your code to source control and have your build server (in our case the OnCheckin build node) attempt to build it.
Poorly referenced binaries.
When you add a reference to a local binary you should follow the best practice of:
- Creating a folder above and/or outside your project’s folder (commonly named “..\lib” or “..\binaries” etc).
- Place your reference’s *.dll files there.
- Add the project reference to this file from within Visual Studio, pointing at this external relative folder.
A common mistake here is to place your *.dll inside the /Bin folder of your project and then reference it from within that folder.
This is incorrect, and will mean that when your project is built using the MsBuild Clean directive, that your file may be deleted before build. If you reference your dependency from an external folder to your project, then this file will remain intact and being included in your build output.
Cached references that have not been recompiled.
Following on from the above mistake, another common issue is to have references to projects that Visual Studio fails to recompile, as for whatever reason Visual Studio fails to think the referenced project’s source code has changed.
This can lead to a situation where it “works on my machine” but when you actually recompile the application on your build server, the executed logic from your latest changes is slightly different to what you tested with locally.
Files that are missing from your Visual Studio Project.
When you are building your Visual Studio application using external assets such as images and sounds, unless you’re using an ASP.Net Website (not a WebApplication) then you need to add these files to your project in order for them to be included in your build output.
If you don’t add your files, and then check these into your source control, any build server will exclude these unreferenced files in their build output. This can lead to websites with missing images, CSS files that don’t make it into your deployment and a number of other issues that can arise from files simply not making your project’s build output.
All of the above problems often cause your application to run fine locally, but then fail to compile successfully on our service, and any locally run build servers you might configure.
MsBuild all things
Behind the scenes the way that our service compiles your code is almost exactly the way any build server would function:
- Download your source code.
- Compile it using MsBuild.
- Run any Unit test binaries.
- Security Scan your application.
- Upload it to your webhost.
Step #2 above is where any misconfiguration in your project surfaces.
Troubleshooting this before you commit your project is easy though; just build and deploy your application locally first. The deploy part is most important, as this means copying a fresh copy of your entire application into a new folder, in doing so helping you to find any issues due to missing files.
To do this, simply execute the following script from the command line (Visual Studio 2015/MsBuild version 14 is being used here):
C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild.exe “[full path to your Visual Studio solution file.sln]” /t:Clean;Rebuild /p:Configuration=Release;OutputPath=C:\temp
What the above does it call MsBuild against your solution file, running a Clean and Rebuild of all of your project files using the Release configuration, and then copies the output to the path C:\temp - Feel free to change this output path to a folder that serves your need better.
By running the above command against your local project files you’ll be able to emulate a fresh clone and build of your project, without having to run an OnCheckin Deployment and see it fails. This should allow you to iterate much faster while also debugging any misconfigurations you’ve made against your project.