.Net Build does not contain output folders from other projects - tfs

We had a Project in our solution called DatabaseCreation - which was responsible for creating the database and running the scripts (contained in directories within the project).
Everything was fine.
We then wanted to make the creation of this database to be available from an app and from a console, so re-factored so that we had ...
DatabaseCreation.Core
DatabaseCreation.App
DatabaseCreation.Console
Core has the directories containing scripts, and the App and Console run them.
When built with Visual Studio the directories containing the scripts are copied to the Output bin directory (either App or Console) but problem is: when the build server runs, the script directories don't get copied to the bin folder.
We've tried with TFS and Team City. I realise I could just copy them over, but its frustrating that it works when building in Visual Studio!
Can anyone put me on the right track please?

Check the Build Type for the files in the scripts directory. Find that by clicking one or many files (ctrl+click) then hitting properties (often f4). You likely want them to be content with Copy Always or Copy if newer.

The files were set to copy always, but the build just wouldn't pick them up.
The slightly awkward work around was to add the files as links from one project to another.
Add Existing -> navigate to other project - Looking for the little arrow on the right of the add button -> press that, Add as link option appears.

Related

TFS Build Drop Folder

I'm currently working on a custom build process and have a problem with the understanding of drop folder. The process creates only some reports which we need for further development. We are using TFS/VS 2012.
What I actually need is either a folder on the buildserver where the Reports are going to be saved and accesable from everyone or on each team members local machine a drop folder. In my opinion the first solution should be better but is it possible, since I'm the only one out of my team which has Access to the buildserver.
If I select the UNC path to the drop folder on the buildserver can other People without Access to this Server use the "Open Drop Folder" button? And how do I even copy files to the drop folder? Is it enough to just do CopyDirectory? In the moment it always says: "This build did not produce any Outputs. The drop Location field is empty..."
I would be really glad if someone could help me.
The purpose of the drop folder is to copy the result of the build from the working folder of the agent and somewhere where it will not be changed by a later build. The share can be on the build server or on another server. No matter what you need to control the permissions to that folder so that whomever needs access has it. Otherwise the Open Drop Folder button will not work.
You can enable so that the build results are copied to the drop location upon build completion. This is a bit different whether you use Build vNext or XAML build. Since you are using TFS 2012, I guess that you are using XAML builds. Drop location is specified under the Build Defaults tab of the build definition.
The output folder from your build will be copied so assemblies, test results etc. will be copied to the drop location when enabled. If there is something extra that you want to be included in your drop, then copy it to the output folder or create it there directly.

.csproj files not getting checked in to TFS

My problem is that in my scenario, I have a project with two parallel project files for different build targets. I have a ProjectName.WP8.csproj and ProjectName.WinRT.csproj, which essentially include the same files.
I am trying to check-in this solution (SolutionName.WinRT.sln) to TFS and I get no errors. All the code changes to the code in the project goes through, but when I check the actual state of TFS, the (newer) PorjectName.WinRT.csproj files are not checked in.
This is quite peculiar since it worked perfectly for the WP8 version. How can I support this kind of scenario?
(If it's not possible, how do I easily migrate my parallel project to another TFS project?)
Just had this come up myself. I had been working on a project for a few days before checking the solution in. During the initial check in for the project, only the most recent file edits were seen by source control. I was able to highlight all the files in the Solution Explorer and select Add to Source Control from the right click menu, but the csproj files themselves did not check in. To do this, I had to go into the Source Control Explorer and open the project directory. From within the directory, right click and select Add Items to Folder. Then you can select the csproj files and you're good to go.

Customizing Drop Folder Structure with TFS Team Build

I'm using TFS 2012 to automate a build of a solution which contains multiple windows services and two web applicaitons.
I've used the guide I found here to customize the build process template so that the windows services are put in a folder structure that I like. Specifically:
\dropserver\droproot\MyApp\BuildNumber\
\Service1
\Service2
\Service3
\Service4
This works great, but unfortunately it doesn't work for web applicaitons. If I used the same strategy for those, I just get the contents of /bin for each web app, rather than the full site contents.
MSBuild typically uses the web application targets to handle this, but for some reason, this doesn't work when you customize the build as I have. I no longer get the _PublishedWebSites folder in the build output. (I'm guessing that's because I cleared our the OutDir property of the MSBuild task.)
Has anybody done something like this and gotten it to work with web applications as well?
I think I can help with this, it looks like in the build targets that the published websites folder isn't created if the OutDir is the same as the OutputPath.
So this isn't perfect, but if you add the following into the csproj file in the first property group, you'll get everything deployed into "\bin\deploy\" including the _PublishedWebsites folder
<DeployOnBuild>True</DeployOnBuild>
<OutDir>bin\deploy\</OutDir>
With a bit of customization, this solution ended up working for me:
http://www.edsquared.com/2011/01/31/Customizable+Output+Directories+For+TFS+2010+Build.aspx
Basically, did what that link recommended, but also leveraged a new solution configuration (which I called TeamBuild) rather than conditional property definitions.
I believe the key to making this all work was the passing of the outputDirectory as the TeamBuildOutDir argument to MSBuild. Embedding this variable reference in the OutDir or OutputPath variable was allowed Team Build to build to the correct staging location and then automatically copy files from that location to the drop folder.
I'm going to take this a little futher and get rid of the whole _PublishedWebSites thing, but that will be done entirely in the build workflow.
EDIT: TFS 2013 supports this natively with a simply build configuration option:
Take a look at this thread as this post as well.
Team Build: Publish locally using MSDeploy
Since you need all the files for your web projects, you need to trigger the publishing process, and by tweaking the destination of that process, you can have all of your files copied where you need them.
I think option (2) from his answer will work for you.
I hope that helps.
As I can see in your reference link, it will just compile and package the binaries. It does not deploy the website by the steps mentioned in that.
If you want to get the .html, .css, .js etc. under the _PublishedWebSites folder, you need to do a Web Deployment. This manually we can do by clicking the publish option from right click menu of your VS project and by selecting Publish Method as File System.
But, since you need to automate this in your build and drop it in custom drop folder, you may need to manipulate your MSBuild script by calling a AspNetCompiler task. You can get more information on this at the MSDN link. By specifying the TargetPath while you call this target you can get your Web files deployed at the appropriate custom drop folder.
Happy Scripting.
Have you check this blog, this solved my problem where I wanted customized TeamBuild Ouput Directory.
Customizable O/P with TFS 2013
Customizaable O/P with TFS 2012 and .NET Framework 4.5

Using wixlibs from another solution with TFS builds

We have installers referencing a wixlib file to get some common functionality. The wixlib is built in another solution then moved to a folder within that solution. When we try to build the installers with a TFS build, we get an error from light.exe:
light.exe: The system cannot find the file '..\..\..\Core\Common\assemblies\v1.0\Common.Wix.wixlib' with type 'Source'.
Our regular projects can reference \assembiles\v1.0, since we have some other common assemblies stored there. How do we get WiX to recognize this location during build?
You are referencing wixlib directly. So as far as I understand the TFS build process, it should be added to TFS project of your solution. TFS project shouldn't be dependent on the output of another non-dependent solution. It is at least bad practice. And in any case you can't guarantee this output would be generated before your project build on server.
As far as I remember, TFS build creates separate folder for each build and gets sources there. So your solutions are no longer on the same folder hierarchy level.
One more point in favor of explicitly copying wixlibs into your installer project: versioning - in this case any bugs made in the common library will not immediately break all projects that reference it. And you can gradually upgrade and test every project. Can you imagine auomatically downloading new version of any 3rd party dll on every build? Any change in that dll will immediately break your application even if changes are not critical to you.
Since the shared component and the active solution are in two separate projects in TFS, the workspace must be setup so that the relative paths for references remain intact. The easiest way to do this is to set your Build Agent Folder structure in Workspace in your TFS Build to have $(SourceDir) represent your root. However, don't change your Source Control Folder - that stays the same.
For example, say you have the following structure:
-TFS
|-SharedComponents
||-MyComponents
|-ProjectArea
||-MyProject
You would want to have the following two items in the build Workspace:
Source Control Folder Build Agent Folder
---------------------------------------------------------------------------------
$/ProjectArea/MyProject $(SourceDir)\ProjectArea\MyProject
$/SharedComponents/MyComponents $(SourceDir)\SharedComponents\MyComponents
This mimics the structure in TFS in your build folder, thus allowing all relative paths to remain intact.
One more note about this configuration: Since you have the shared components in another location, you may want to create a solution folder in MyProject and add the components that you are using to it. This will ensure they get pulled automatically when anyone loads your project from TFS - they won't have to go back and pull down the share components folder separately after discovering a build error.

How do you share scripts among multiple projects in one solution?

In case the question wasn't clear. I have 3 MVC projects in one Solution. Every time I create a new project it adds the "Scripts" folder with all the .js files I'll ever need. I don't want to have this created every time for every application. Is there a way to reference scripts from a central folder in the solution so all applications/projects can share one common script folder with all the scripts common among them?
Edit:
Please explain the pros and cons of doing this if there are any...now I'm curious.
Here is what I would recommend:
Right click the solution and create a New Solution Folder called Common Javascript Files (or whatever you feel like calling it.
Right click on the Solution, click Open Folder in Windows Explorer,
or navigate there manually for other versions of Visual Studio :(
In the solution directory, create a directory with the same name as the solution folder (solution folders do not normally match directories at the source code level but this will for sanity sake).
In this new directory, add files that need to be shared between solutions.
In Visual Studio, click the solution folder and select Add - Existing Item.
In the file selection dialog, navigate to the directory previous created, select the file(s) added to the directory and click Add.
In each Project that needs a shared file, right click on the project (or directory within the project) and click Add - Existing Item.
Navigate to the shared Directory, Select the files and click the drop down arrow then click Add As Link.
Now the files in the projects are essentially short cuts to the files in the Solution Folder. But they are treated as actual files in the project (this includes .CS or Visual Basic files, they will be compiled as files that actually exist in the project).
PROS
Files are truly shared across projects at Design time
Only the files needed for each project can be added, it's not all or nothing
Does not require any configuration in IIS (virtual directory etc)
If the solution is in TFS Source control, you can add the Directory to the TFS Source and the shared files will be source controlled.
Editing a file by selecting it in the Project, will edit the actual file.
Deleting a Linked file does not delete the file.
This is not limited to JS files, linked files can be ANY file you might need (Images, Css, Xml, CS, CSHTML, etc)
CONS
Each deployment gets it's own file.
There is a small learning curve when understanding that Solution Folders are not Directories that exist in a Solution Directory.
The best thing to do, imo, is to roll your own CDN... Basically just create another site in IIS and give it it's own binding, e.g. "http://cdn.somedomain.com"
Then store all of your css/js/fonts/shared images etc on the CDN site and link to them from your other sites.
Doing so solves 2 problems,
All of your stuff is shared when it needs to be and you only have to manage 1 revision per file.
Your users browsers can cache them in 1 single location instead of downloading copies of your stuff for every site that uses them..
I added this answer because I see a lot of people referrencing creating virtual directories. While that does indeed share the files, it creates multiple download paths for them which is an extreme waste of bandwidth. Why make your users download jquery.js (1 * number of sites) when you can allow them to download it once on (cdn.somedomain.com).
Also when I say waste of bandwidth, I'm not just talking about server bandwidth, I'm talking about mobile users on data plans... As an example, I hit our companies HR site (insuance etc) on my phone the other day and it consumed 25mb right out the gate, downloaded jquery and a bunch of stuff 5 times each... On a 2gb a month data plan, websites that do that really annoy me.
Here it goes, IMO the best and easiest solution, I spent a week trying to find best and easiest way which always had more cons than pros:
Resources(DLL)
Shared
images
image.png
css
shared.css
scripts
jquery.js
MvcApp1
Images
Content
Shared <- We want to get files from above dll here
...
MvcApp2
Images
Content
Shared <- We want to get files from above dll here
...
Add following to MvcApp1 -> Project -> MvcApp1 Properties -> Build events -> post build event:
start xcopy "$(SolutionDir)Resources\Shared\*" "$(SolutionDir)MvcApp1\Shared" /r /s /i /y
Here is explanation on what it does: Including Build action content files directory from referenced assembly at same level as bin directory
Do the same for MvcApp2. Now after every build fresh static files will be copied to your app and you can access files like "~/Shared/css/site.css"
If you want you can adjust the above command to copy scripts from .dll to scripts folder of every app, that way you could move some scripts to .dll without having to change any paths,here is example:
If you want to copy only scripts from Resources/Shared/scripts into MvcApp1/scripts after each build:
start xcopy "$(SolutionDir)Resources\Shared\Scripts\*" "$(SolutionDir)MvcApp1\Scripts" /r /s /i /y
This is a late answer but Microsoft has added a project type called Shared Project starting Visual Studio 2013 Update 2 that can do exactly what you wan't without having to link files.
The shared project reference shows up under the References node in the
Solution Explorer, but the code and assets in the shared project are
treated as if they were files linked into the main project.
"In previous versions of Visual Studio, you could share source code between projects by Add -> Existing Item and then choosing to Link. But this was kind of clunky and each separate source file had to be selected individually. With the move to supporting multiple disparate platforms (iOS, Android, etc), they decided to make it easier to share source between projects by adding the concept of Shared Projects."
https://blogs.msdn.microsoft.com/somasegar/2014/04/02/visual-studio-2013-update-2-rc-windows-phone-8-1-tools-shared-projects-and-universal-windows-apps/
Info from this thread:
What is the difference between a Shared Project and a Class Library in Visual Studio 2015?
https://stackoverflow.com/a/30638495/3850405
A suggestion that will allow you to debug your scripts without re-compiling the project:
Pick one "master" project (which you will use for debugging) and add the physical files to it
Use "Add As Link" feature as described in Eric's answer to add the script files to the other projects in solution
Use CopyLinkedContentFiles task on Build, as suggested in Mac's comment to copy the files over to the second over to your additional projects
This way you can modify the scripts in the "master" project without restarting the debugger, which to me makes the world of difference.
In IIS create a virtual folder pointing to the same scripts folder for each of the 3 applications. Then you'll only need to keep them in a single application. There are other alternatives, but it really depends on how your applications are structured.
Edit
A scarier idea is to use Areas. In a common area have a scripts directory with the scripts set to be compiled. Then serve them up yourself by getting them out of the dll. This might be a good idea if you foresee the common Area having more functionality later.
Most of the files that are included by default are also available via various CDN's.
If you're not adding your own custom scripts, you may not even need a scripts directory.
Microsoft's CDN for scripts: http://www.asp.net/ajaxlibrary/cdn.ashx

Resources