nilesh
nilesh

Reputation: 14289

git submodules vs maven artifacts

Our rest service development is handicapped and slowed down with current structure. I have tried to capture it in a picture below. Some explanation about the diagram

Most of the code is under v1 or v2. RestServiceA/B don’t have much code in them apart from resources, configurations etc. So, there is a tight coupling here.

Problem with this approach is that, for a given feature I make changes in let’s say v1, I need to build the jar, update its version in let’s say RestServiceA and test. This needs to repeat for every new commit. Additionally, I would need to publish my own snapshots to test outside of local.

To avoid this mess, I was thinking of using github submodules. However, my knowledge is limited. Can someone help if below understanding is correct and if I am missing any obvious loopholes if were to choose this approach. I’m open to any alternative approach. Thanks!

enter image description here

Upvotes: 1

Views: 1957

Answers (1)

Dmitry Pavlenko
Dmitry Pavlenko

Reputation: 8958

We have a similar project structure and ended up with the following solution.

  1. There's a Git repository per each module ("module repositories"). In your case that would be all repositories that you've mentioned in the post:
v1-lifecycle, v1-utils, v2-lifecycle, v2-utils, prd-common, RestServiceA, RestServiceB, RestServiceC
  1. Each module repository contains an usual Maven project that can be built independently, this is more or less like what you have now, but...
  2. ...The module repositories do not have submodules, they only refer to each other as Maven dependencies.
  3. On every push to the module repositories CI uploads the new artifacts to Maven if the tests pass (or it doesn't if not).
  4. In addition to module repositories, there's a single ("parent") Git repository that contains other module repositories inserted into its tree (I'll explain below what it means). So the parent repository contains all the code in some sense.
  5. The parent repository's pom.xml includes all other modules in its trees using Maven's <modules> tag:
    <modules>
        <module>module1</module>
        ...
        <module>moduleN</module>
    </modules>

And the tree structure of the parent repository looks like:

├── module1
├── ...
├── moduleN
└── pom.xml

This allows us to build and test all the projects before committing and before publishing the artifacts using mvn test, mvn integration-test, or mvn package.

Also this architecture makes cross-module refactorings much easier as IDE opens all the code. So we do all the development from the parent repository directly.

I wrote an article describing this setup on a tiny example of just 2 modules.

Here comes full disclosure: the project we're developing is Git X-Modules (is a replacement to Git submodules) and it uses itself instead of Git submodules to insert module repositories into the tree of the parent repository.

So by inserting module repositories into the parent repository I mean using of either:

  • Git submodules; OR
  • Git X-Modules, if you choose that way like us

to create module1...moduleN directories at the root of the parent repository.

The difference is that in case of Git submodules the module1...moduleN directories at the root of the parent repository will be links to their corresponding Git repositories. E.g. if we change them from the parent repository, we have to commit and push into each of the individual module repository.

In case of Git X-Modules they all be just normal Git directories, so we have to commit and push only once, and on the server side the push is converted to pushes into individual module1...moduleN repositories. I hope you get the idea. The branching is also easier in this case.

Regarding your last question, afaiu this was needed because you don't want to test changes before committing them. When having the parent repository with Maven modules, you can just run "mvn test", "mvn integration-test", or even perform manual testing of all the changes before committing and pushing, so the question becomes irrelevant, as I understand.

In the worst case the developer can create a new branch directly in the parent repository and push just that branch to make CI test it and then merge the branch (or cherry-pick from it) it everything is ok. No temporary upload to Maven is involved.

Upvotes: 1

Related Questions