Gradle - multiple project and git repositories - spring

We have 3 projects and a 4th one that is shared among them.
A multiple project in gradle requires one to create a wrapper project and include all the sub projects in it.
Each of our sub projects are being worked on by different team members and we use git as an svn.
Our concern before going into gradle is the fact that we will only have 1 git repository that consists of the wrapper project with all sub projects instead of 4 different repos, each for each sub project.
1) Are we missing something?
2) Is it possible to create 4 repos on a multi project?
3) One of our requirements is to deploy a single war (for example only webapp #1 out of the 4)--does using the multi project template make it possible?

ad 1) You have some choices:
Use a single Git repo.
Use multiple Git repos and exchange artifacts via a binary repository (e.g. Artifactory), with artifacts being produced on a regular basis by CI jobs.
Use something like Github submodules to create a "virtual" overall Git repo (wouldn't recommend this one).
ad 2) Gradle doesn't really care how many Git repos the build is comprised of, as long as everything that settings.gradle points to (at least all build scripts) exists on disk when the build starts. Of course it may be inconvenient for developers (and CI admins) to juggle multiple Git repositories and put them in the right (relative) locations.
ad 3) Yes.

I stumbled across this question on the same quest, and only later somebody pointed out another option to me (it's really a variant of the third choice listed under ad 1 in https://stackoverflow.com/a/20678444/1016514), which seems like an elegant hack:
You keep the subprojects in separate Git repos, and from within your root project point to them by setting the respective rootDir properties. This requires a fixed checkout layout, obviously, but that would usually be the case anyway.
The approach is described here: https://medium.com/codequest/gradle-multi-project-build-substituting-jar-dependencies-with-local-projects-4a5323f8680b
Update with Gradle 7.3+: this will now yield a warning, and likely not work after some point in the future:
Subproject ':xyz' has location '...\xyz' which is outside of the project root.
This behaviour has been deprecated and is scheduled to be removed in Gradle 8.0.
Consult the upgrading guide for further information:
https://docs.gradle.org/7.3.1/userguide/upgrading_version_7.html#deprecated_flat_project_structure

Related

Automatically create Package Feed on the event of a feature branch creation

The issue is known to many maven based projects using feature branches. In maven, there is no concept of a branch. Now in a git-flow environment there are basically 2 ways to deal with the build artifacts:
modify the version number to something like "featureX-1.0.0-SNAPSHOT".
Separate the SNAPSHOT repositories to get an isolated build and dev environment. Use a maven extension to determine the branch and select the proper repositories early in the process.
Variants of the two seem to exist, but both have its drawbacks. We would like to go in our team to option 2 and share the pipelines to publish maven artifacts to separate package feeds.
Is there any way to automate the creation of package feeds on the event of a git branch creation?

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.

Build dependencies and local builds with continuous integration

Our company currently uses TFS for source control and build server. Most of our projects are written in C/C++, but we also have some .NET projects and wouldn't want to be limited if we need to use other languages in the future.
We'd like to use Git for our source control and we're trying to understand what would be the best choice for a build server. We have started looking into TeamCity, but there are some issues we're having trouble with which will probably be relevant regardless of our choice of build server:
Build dependencies - We'd like to be able to control the build dependencies for each <project, branch>. For example, have <MyProj, feature_branch> depend on <InfraProj1, feature_branch> and <InfraProj2, master>.
From what we’ve seen, to do that we might need to use Gradle or something similar to build our projects instead of plain MSBuild. Is this correct? Are there simpler ways of achieving this?
Local builds - Obviously we'd like to be able to build projects locally as well. This becomes somewhat of a problem when project dependencies are introduced, as we need a way to reference these resources or copy them locally for the build to succeed. How is this usually solved?
I'd appreciate any input, but a sample setup which covers these issues will also be a great help.
IMHO both issues you mention fall really in the config management category, thus, as you say, unrelated to the build server choice.
A workspace for a project build (doesn't matter if centralized or local) should really contain all necessary resources for the build.
How can you achieve that? Have a project "metadata" git repo with a "content" file containing all your project components and their dependencies (each with its own git/other repo) and their exact versions - effectively tying them together coherently (you may find it useful to store other metadata in this component down the road as well, like component specific SCM info if using a mix of SCMs across the workspace).
A workspace pull wrapper script would first pull this metadata git repo, parse the content file and then pull all the other project components and their dependencies according with the content file info. Any build in such workspace would have all the parts it needs.
When time comes to modify either the code in a project component or the version of one of the dependencies you'll need to also update this content file in the metadata git repo to reflect the update and commit it - this is how your project makes progress coherently, as a whole.
Of course, actually managing dependencies is another matter. Tons of opinions out there, some even conflicting.

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.

Should Git Repo's be at the Solution Level or Project Level in Visual Studio

If I have a C# solution with multiple projects in it, what would be better, to have the Git repo created in the solution folder, or in each individual project folder? Multiple developers will be working on the projects. What are your experiences with this?
I use several (sometimes overlapping) solutions to contain a collection of related independent applications and shared libraries. As others have mentioned, you really don't want to have a single Git repository containing the source for multiple, independent projects as it makes it much too difficult to track isolated changes.
So, if your solution is structured as mine is then you will definitely want individual Git repositories for each project. This has worked well for me for ten to twelve applications and doesn't create as much maintenance overhead as you might think.
If your solution is truly monolithic (and you're sure you want it that way forever and ever), then it probably makes sense to only have a single repository.
It depends. git repositories are most suited to containing a single configuration item with its own independent lifecycle. If your projects have their own release cycle and are shared between multiple solutions then it might make sense to have them in their own repositories. Usually, though, it is the solution that represents a configuration item with all the constituent projects forming part of the same build. In this case a single git repository at the solution level makes more sense.
git submodule is probably worth consideration here. Each project gets its own repo, the solution gets a repo, and the projects are submodules.
I assume that your solution represents some kind of a product while the projects are just a part of the product.
In this situation I would create the repository on the solution level. This way it is a lot easier to build the whole product at once, especially if the projects depend on each other.
Some though and 3 solutions on the subject can be read on that blog:
https://www.atlassian.com/blog/git/git-and-project-dependencies
package management tool, i.e. nuget in VS, so using reference to a package/compiled module
git submodule (only with command line in VS?)
other build and cross-stack dependency tools
Another solution is just to add a project from the other repo and let it out of the current repo, and latter use the Team Explorer to commit its changes.

Resources