Integrating Multiple project parts into one GIT repo - visual-studio-2010

I've got some questions and here's the scenario:
I've got one big Sitecore CMS website (Proj A) that has a ton of native dll's as well as custom ones that we've created to enhance funct on the site.
The custom dlls are generated by individual VS projects (Proj B, C & D) that we manually compile and then move the finished product (dll) to Proj A bin directory.
We currently have Proj A repositories for PROD, Integration, Public as well as every developer typically clones a copy of PROD to work features/fixes.
Proj B, C & D are not setup under version control as of yet because we havn't found a way to easily integrate it's release into Proj A.
Using the integration manager workflow, we let everyone do their feature/fix and then we merge it to an Integration repository. At this point we're ready todo the following:
Recompile Proj B, C, & D
Robocopy release files from each project to the Proj A bin folder
Recompile/build Proj A and deploy to Integration server.
Questions:
Would you include Proj B, C, & D in the directory structure of Proj A? If so, when compiling each project, would you make the release directory for the each project the Proj A Bin directory?
How/when would you automate the inclusion Proj B, C, & D "dlls" into Proj A bin directory.
Can you recommend a way that would streamline the integration of these files?
NOTE: I've researched Reps within Reps as well as submodules but not sure if i need just a hybrid of both.
Any recommendations would be greatly appreciated.
Thanks and have a nice nite.
foxtrotzulu

We have a similar situation with an ASP.NET Web application that depends upon other projects.
Our solution has been to create the Web application and each dependency as a separate VS solution in a separate repository, then define the repositories for B, C, D as submodules in the repository for A.
The VS solution for A includes the copies of the projects B, C, and D that are provided by the submodules, and these projects are project references in the project for A.
This solves 1 and 2 because you can just build project A in the normal way and B, C, and D will automatically be built from source and the DLLs copied into the build directory for A.

If you create a solution you can add your website/webproject and your other projects to this solution. if you then add references from the website/webproject to those "custom dlls" the dll's should get copied over (by default, otherwise there is an option for this iirc).
I would automate them if they were specific for Proj A, if they are things like internal APIs, utilities etc that all projects use, I wouldn't include them in the Proj A solution.
Not sure if I would recommend this way, but if you have the custom DLLs built somewhere automatically (using CruiseBuild or the like) and then committed to the repository you could add an External "update". But this could just as easily be a problem, if new changes would break Proj A often.
This is by no means a complete offer, but maybe a partial answer to your question.

Dont know if this helps anyone but just wanted to followup my own questions:
Questions:
Would you include Proj B, C, & D in the directory structure of Proj A? If so, when compiling each project, would you make the release directory for the each project the Proj A Bin directory?
We decided to keep proj A (Sitecore web) as a separate repository inside a Sitecore rCS folder.
This folder contains repositories and a DLLs folder:
dlls
dev1_PUBLIC
dev2_PUBLIC
dev3_PUBLIC
INTEGRATION_STAGING
PRODUCTION_STAGING
To start a feature/fix all developers install a vanilla Sitecore and do a PULL to update there local master from PRODUCTION_STAGING
Checkout a local feature branch, naming it according to ticket/project. Run local updateDll.bat to pull down updated dlls.
Do work, commit often, test and verify
PUSH local master
PUSH to "xxxx_PUBLIC".
Contact Integration manager so that he/she can PULL from public to INTEGRATION_STAGING.
IM pulls to Integration (QA), runs local updateDll.bat, notifies dev to go ahead and test integration to Sitecore or other project
If test is verified, IM will schedule PULL to PRODUCTION and run local updateDll,bat. If Production is good, IM will PULL changesback down to PRODUCTION_STAGING so that a fresh copy is ready.
We decided to have proj B, C and D (C# components) have their own repository per project inside a dotNetProjects folder.
Each project folder contains a number of repositories:
dev1_PUBLIC
dev2_PUBLIC
dev3_PUBLIC
INTEGRATION_STAGING
PRODUCTION_STAGING
To start a feature/fix all developers CLONE a copy of PRODUCTION_STAGING to there local pc.
Checkout a local feature branch, naming it according to ticket/project.
Verify output folder for project points to "releasedlls" folder in dotNetProjects projects. Do work, commit often, test, verify and build project. verify dll datetime stamp.
PUSH local master
PUSH to "xxxx_PUBLIC".
Contact Integration manager so that he/she can PULL from public to INTEGRATION_STAGING.
IM pulls to Integration (QA), runs local updateDll.bat, notifies dev to go ahead and test integration to Sitecore or other project
If test is verified, IM will schedule PULL to PRODUCTION and run local updateDll,bat. If Production is good, IM will PULL changesback down to PRODUCTION_STAGING so that a fresh copy is ready.
How/when would you automate the inclusion Proj B, C, & D "dlls" into Proj A bin directory?
Output folder for each project is set to dotNetProjects/releasedlls folder which is not a repository, just a folder to house dll related to SItecore.
Developers adding features/fix to sitecore must run updateDll.bat locally to get the newest version of the dll. Here is the simple script:
xcopy /E /Y "\\servername\dotNetProjects\ReleaseDlls\*.dll" C:\development\sitecore\WebSite\bin
NOTE:
Steps 4-8 are identical above, the
editor was giving me a headache so I
just left the redundancy.
With all the dlls involved, in regards to Sitecore, we still wanted to gitignore dlls because it could be a headache for our business users. So to maintain dlls as an ignored file our workaround is the quick fix above. This is not what we'd like it to be but if it
works for you, use it, if not, disregard.

Related

How can I achive Continuous Integration and Deployment for many projects in one solution?

What we use:
We use mercurial and bitbucket for repositories. Appveyor and kudu for continous integration and deployment. We are using visual studio 2015 as IDE.
What we have:
We have different web projects. They share some other projects. All of web projects have their own solution. Every solution have their own repository.
If there is change on develop branch. Appveyor builds this repository, tests and deploys it.
If there is change on default, kudu builds this repository and deploys it.
What we want:
We want to merge all of these projects in one solution. But I couldn't figure it out, how I can achive continous integration or deployment.
If I change something on webproject1, I just want to build and deploy webproject1. The other webprojects in solution neither should be built nor deployed.
Perhaps a single repository will help you. Using relative path to include the shared libraries from your different applications.
Each application can still have its own Solution file and your CI setup also stays as it is. What changes is that the shared projects you have across all applications will be referenced with relative path. E.g.:
Repository root\Core\Component1\Component1.csproj
Repository root\Core\Component2\Component2.csproj
Repository root\Applications\App1\App1.sln
Repository root\Applications\App1\Domain\Domain.csproj
Repository root\Applications\App1\Web\Web.csproj
Repository root\Applications\App2\App2.sln
Repository root\Applications\App2\Domain\Domain.csproj
Repository root\Applications\App2\Web\Web.csproj
Now your different application can include the Core\Components they need by adding existing project to solution using relative path.
Your continuous integration system will have VCS triggers watching the app and dependencies so only relevant changes fire a build.
So if App1 developer makes a change on Component1, and Component1 is also used by App2, the build server will trigger a build to App1 and App2, signaling any breaking changes. However if App2 doesn't not depend on Component1, then only App1 will build.
This is achieved by configuring the build triggers for your applications.
One benefit of this strategy vs having a single .sln is that you won't have to build everything each time you build solution (nor configure what projects to build each time you work on a different app)
Also note that you can achieve this with multiple repositories. But that means you'd need to check them out at the correct location so your relative paths work. It's also quite obscure since if you checkout App1 and try to build it. It simply won't work and you'll have to figure out which other repos to check out, etc.
You are using Mercurial but FYI, the way (one of) this would be handled with Git is with submodules.

Changing location of referenced project in VS solution

I use Team Foundation Server for source control. All of my projects use a structure that have dev, main, and release branches.
For the purposes of this question, I have 2 TFS projects, one is my application and the other is a shared library. The solution file for my application includes the shared library project (even though it is in a separate TFS project) because it makes it easier to debug. So I have a solution in 1 TFS project pointing to a project in another one.
The problem I'm running into relates to branches. What I'd like to do is point to the dev branch version of the shared library when in the dev branch of my application's solution. Similarly I want the main branch version of my solution to point to the shared library in the main branch, etc.
Does anyone have ideas of how to handle this?
I can't tell you if this is the best way, but I'm pretty sure it will work if you don't come up with anything better.
Create a symbolic link between the two directories, and map the project using that.
Add a pre-event MSBuild script to delete and recreate the symbolic link for each build based on the current branch. For example:
rmdir MyProject
mklink /d MyProject c:\dev\Main\MyProject
You'll probably want to put this in a batch file and call that.

What is the recommended way to setup projects like this?

We are working on a large project. The project has multiple external sites and multiple internal sites all stored in Subversion.
The external sites allow a customer to make requests of various things we provide, pay utility bills and more. We decided to break many of these functions apart because most work completely different than the others. So this is one Visual Studio solution with the WebUI and the database layer broken into two projects each. For instance, utility billing has a Utility.WebUI project and a Utility.Domain project. All DB/business logic is kept in the domain project.
The internal sites bridge the gap between the back-office system (IBM i) and the web database. Also will replace/enhance some of our older RPG programs. In theory they should use the exact same database logic that the external sites use because they access the same database right? What is the best way to reference these projects from a different solution? Should I just add a reference to the dll or should I import that project from the external application solution into the internal application solution?
This comes down to that we have two developers working on this project. Myself, I do most of the back-end coding. The other developer does most of the GUI coding. So we need to make sure that this project works on multiple workstations.
Does this make sense? Any thoughts?
Use the svn:externals property to reference the shared project into your project(s).
You have to choose between 1) referencing the directory containing the shared project's source code (i.e. where the csproj and cs files are located) or 2) referencing the directory containing the shared project's build output (assembly / dll).
I normally prefer method 1) since it makes modifications to the shared project's source code easier (you can make changes without having to open the shared project's solution in a second instance of Visual Studio). If you don't intend to make changes to the shared project often then method 2) might be better. It reduces compile time and prevents accidental modifications of the shared project's source code. Both methods are fine - matter of taste.
It is recommended for both methods that you version your shared project. i.e. create tags with version numbers and reference the tags, not the trunk. When a new version of the shared project comes out you can update the svn:externals property of your other project(s) with the new version number, run "svn update" to download the new version of the shared project, and recompile. This works especially well if you have a build server for the shared project that does the tagging for you automatically.
I think you can use a sort of "commons" solution that contains the common projects and then refer to these projects in you main solutions using SVN external pointing to the project folder in the SVN trunk.
Commons SVN repository must follow the suggested repository structure (trunk, branches, tags) to have always stable commons projects.
In this scenario you can consider to use a dependency management tool, such as NPanday or NDepend, where you must declare to which version of which assemblies every project depends on; using these tools you can have a local repository (such as Artifactory or Nexus) of binary assemblies to refer to, or choose to use SVN externals to refer directly to source code.

How to handle shared projects correctly in TeamCity

Let's say I have two "projects" within TeamCity, which are two websites, that each use a shared library that isn't within the svn path of the website. Here is the svn structure to make it more clear:
Website A: svn://root/web/websitea (uses shared library a)
Website B: svn://root/web/websiteb (uses shared library b)
Shared Library A: svn://root/shared/liba
Shared Library B: svn://root/shared/libb
How would I setup a teamcity project for website a? Right now I have it point to the svn://root but that would make it trigger a build even if website b or shared library b was changed, which is not right. What I really need is a way for it to trigger a build only if there is a change in svn://root/web/websitea OR in svn://root/shared/liba.
I tried setting up two vcs roots within the same project which point to the two svn paths above, however there doesn't seem to be a way to set a working directory for each vcs root. For this reason, it ended up just copying the contents of the two svn paths directly into the root of my build directory instead of putting them in the proper places (C:\Build\Web\WebsiteA & C:\Build\Shared\LibA).
TeamCity's checkout rules functionality is able to support the setup you're describing. My team uses it to do something similar to what you're trying to do.
First, set up a single SVN Root. The URL of this root would be something like this:
svn://root/
Then set up the following checkout rules.
For Project A:
+:web/websitea=>/web/websitea
+:shared/liba=>/shared/liba
For Project B:
+:web/websiteb=>/web/websiteb
+:shared/libb=>/shared/libb
The TeamCity documentation on checkout rules isn't totally clear about this point, but only the particular paths you have included will be used to trigger builds. This should meet your need to have only changes is websitea and liba trigger its build (and the same for B).
In addition to what Eric mentioned, if you need the entire source root to be checked out, but only trigger the build based on particular paths, you can edit the VCS Trigger rules in the Build Triggering section to have something like:
+:web/websitea
+:share/liba

How to merge two git repositories containing Xcode projects

Picture the following scenario. I have an iPhone application contained in Xcode project A, and an iPhone application contained project B, each one of these Xcode projects is contained in a separate git repository. There are a bunch of things that I would like to do:
Be able to create a library or Framework from parts of project B that I would then use in project A or other projects. How can I create a Framework in Xcode, and then clone it into another project using git, so that any changes I make to the framework are reflected. Ideally the framework would remain part of the larger git repository and Xcode project B.
Without creating a framework, how can I do the above, namely, import a part of a git repository (call it B1) into another one A, so that I can still keep on developing and improving B1 as part of B, but can eventually see those changes in A?
Last point: is there an easy way to merge two Xcode projects (if they have fairly similar structure) using git, or a recommended way, at least to make it as painless as possible.
the first two you ask about can be done using
git submodule --add <remote repository>
manpage
As for merging you could try creating git project C with git project A and project B as remote repositories. Assuming no or little overlap in files they might just merge together seamlessly. I think however that submodules is probably a better bet.
The best solution I have found to this problem is basically to create a static library out of any code I want to use between the two projects, and then import that from the other Xcode project. Very well explained in this post here:
Shared Libraries
This allowed us to keep the repositories separate, but still pull from one another as needed.

Resources