Hi guys. I guess this is more of a Gradle related ...
# announcements
o
Hi guys. I guess this is more of a Gradle related question but I’m just gonna post it here hoping for some sort of advice. Did anyone experience configuring (and working on) a monorepo containing multiple libraries? Lets assume that these libs can depend on one another AND and can also appear as dependencies in other projects (in other repos). This means that I wanna be able to: 1. Build the artifacts that are contained inside this mono repo in a way that’ll respect my dependencies. Assuming I have three libraries called A, B and C, while A depends on B and C is entirly independent, I wanna build both B and A in case there’s a change in B, but I don’t want C to be built) 2. Publish all artifacts that were changed during the build process to a local artifactory, later to be consumed by other components stored in different repositories I can share some more info on DM if needed, for example the tools used in my organisation with which I wanna achieve what I mentioned above. I encountered Gradle’s composite builds and multi-project builds but I’m still not quite sure about the differences and what fits better for my needs. Would appreciate any kind of help. Thanks in advance!
c
Yes, Gradle does this kind of stuff very well. Generally, I’d say that if you want to have all libraries published at once (usually with the same version numbers), use multi-project build. If you want to version and release the libraries independently of one another (release v1.1 of B and A, but keep C at 1.0 and don’t publish it), then a composite build might be better. Composite builds are typically useful when each build is a separate Git repo, but those repos depend on each other. Multi-project builds are the more traditional “monorepo”, where a single repo has multiple independant but interlinked sub-projects.
m
To add to Casey's comment. Composite builds is a feature added to Gradle to ease working with a library that's an artifact dependency (i.e. groupartifactversion) as opposed to a dependency in a multi-module project. Before this existed, you'd have to build the library, and publish to a local repository. Update your project to point to the new version, and then build it. Time consuming. Composite build allows you to leave the original artifact dependency in place in your build file, but update during build to point to a local project. Gradle will then build the library, if required, update the build dependency tree to reference the local build, and compile your project. IntelliJ natively supports the concept of Composite builds, too, which greatly speeds development time when making changes to a library, and it's dependent project. https://confluence.agile.bns/display/ACCP/USER+GUIDEs?focusedCommentId=227413695#comment-227413695 https://www.jetbrains.com/help/idea/work-with-gradle-projects.html
o
@Casey Brooks @Mike Thanks for the detailed responses! According to what you guys described (and if I take the external dependencies I described out of the equation) - multi-project builds should fit better to my use case. Having said that - the multiple libraries in my monorepo aren’t necessarily related or depend on in other (some are, some aren’t). In addition to that, along time we might have quite a large number of libraries, which leads me to think that I wouldn’t want to build all these libraries on each change or have all these libraries share the same version. Is my use-case out of the ordinary? cause it seems like I’m looking for some kind of mashup of these two approaches.
c
I, personally, have no problem releasing a new version of a library in a monorepo if it has no changes, for the sake of keeping everything at the same version. And publishing a lot of artifacts from a single repo isn’t a huge problem either, I manage a project that publishes nearly 40 artifacts each release. Just make sure you’re deploying from CI and you’ll never notice the deploy times. And you’re use-case isn’t exactly unheard of, it’s a very valid desire. Some monorepo tools like Lerna JS handle this exact case, but I don’t think it’s the best DX for a single monorepo to contain multiple independent versions. My personal expectation is that a single Github repo has a single version which I can easily find at the top of the README, in a Changelog file, or in the Releases/Tags. If I have to hunt through your repo to find the version of a particular sub-library, then it probably should be in a separate repo. And that’s mostly the way Gradle is set up too, I can’t think of anything off the top of my head to manage independent continuous releases from Gradle. It’s set up to publish all subprojects at once, and you’d have to do some work to do otherwise in a monorepo.
💯 1
o
Thanks @Casey Brooks, much appreciated