Thursday, 18 April 2013

CI build, deployment Items and Copy to output directory

As I started to write this blog post, I must admit, I struggled with find an appropriate heading for it. We can put this blog post in the "How I got burnt category" category.

So, we are running our CI builds using TFS 2012 and with very little customisation to the out-of-the-box build template and it all works a treat. However, occasionally our builds are failing with the following error

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3686): Unable to copy file "C:\CI\77\src\...." to "C:\CI\77\bin\....". Access to the path 'C:\CI\77\bin\....' is denied.

Looking closely, there were two traits of the files for which we were getting this error.

  1. The files had the "Copy to Output directory" property set to "Copy Always".

  1. The files were present as an "Deployment Item" in a Test class.

We had a few XAML files, which had to be loaded dynamically in our tests, so the DeploymentItem was needed.

The error happened in the  "_CopyOutOfDateSourceItemsToOutputDirectoryAlways" target in the Microsoft.Common.targets file, which is executed when MSBUILD is attempting to copy all files with the setting "Always Copy to output directory" to the output directory.

The error seems to have happened because the CI Build tried to copy a file after it has been deployed as a deployment item. We did have BuildInParallel attribute set to true. In our case, we realised that the "Copy to output directory" was not needed, so we changed the setting to "Do not copy". In other scenarios where both the conditions are needed, the solution would be to set the BuildInParallel parameter to false. 

No comments: