While working with Release Management a new deployment suddenly gave an error:
ERROR: The deployment for release template ‘XXXX’ has not been completed successfully. Check the releases history for more details. Exit: 1
The release history didn’t gave much information but the Event Viewer showed the following:
The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.: rnrn at System.IO.PathHelper.GetFullPathName()
So what’s happening here
When a new release starts, the Deployment Agent on your server copies all required data from your Release Management server to a local folder on your deployment server. For example, if you have a component MyDatabase that is located in the root of your build package, you can use a forward slash in your component configuration to tell Release Management to look for the component at the root of your build drop location.
Now all the data in your build folder gets copied over to the deployment server and gets stored at:
C:Users
The problem I was having was that the customer not only had a database project but also a really long path and filename in a web project. The website got published to _PublishedWebsitesWebsiteName and got copied to the deployment server. That together with the temp folder and the component name was way to long.
Now off course we could have shortened the path name. But the underlying problem was that not only our database was copied but the complete build package. This is a waist of time and resources.
Splitting the build package
To resolve the issue, you can change the build to output each project in his own folder. This way, the build drop location would contain a folder MyDatabase with only the database files. It would also contain a specific folder for the website with the published website files.
You can configure this by adding the following MSBuild argument to your Build Definition:
/p:GenerateProjectSpecificOutputFolder=true
Now the structure of your build drop location changes and contains a separate folder for each project. This means that a folder MyDatabase is created with all the database files in it. Changing your component to point to MyDatabase now makes sure that only the required data gets copied to your deployment server.
What about Output location
In TFS 2013 a new option Output location was added to the Build Definition. This property can be set to:
- SingleFolder
- PerProject
- AsConfigured
PerProject does not do what you initially think. The PerProject option creates a single folder for each project that you specify under the Build –> Projects option at 2.1. This means that if you build two solutions as part of your build, SingleFolder will combine the results of those two solutions into one folder while PerProject will output a folder for each solution.
AsConfigured won’t copy the build output anywhere. Instead, you can attach your own scripts that copy the build output from your build location to your drop folder. This gives you total freedom. In this case however, using the GenerateProjectSpecificOutputFolder MSBuild argument did the trick.
Comments? Feedback? Questions? Please leave a comment!