TL;DR: Use release dependencies instead of snapshot ones.
Case to consider when choosing between snapshot and release dependencies is when changes in some component (A
) break a dependent component (B
).
When this happens, you need to fix it, but there are two options, one of which might turn out preferable depending on your project specifics.
One option is when you prefer to fix the issue immediately, even though it may come at cost of distracting developer working on component A
. Benefit of this approach is its conceptual simplicity - it relieves developers from the need to memorize, maintain and update dependencies between components, because instead their efforts are focused on simply keeping all the most recent versions of components in sync.
In this case, release dependencies don't offer anything appealing compared to snapshot ones; rather the opposite - these would introduce an extra step / effort to release updated component A
to be able to test whether dependent component doesn't break anymore.
- By the way, Maven provides support for a simplest form of snapshot dependency preference: multi-module projects, where handling snapshot dependencies between modules is made as easy as it gets (though this comes at the expense of simultaneous releases, which is sometimes undesirable - eg when components / modules tend to change at very different pace).
An opposite option is when you would prefer to postpone integration fixes in the component A
, for example when you believe that in your project it is more important for developer to strongly focus on the changes made in it and switch their efforts to integration later. This could be the case when dependencies between components are "loose", small, carefully designed and slowly changing interfaces.
- For example, if you already have carefully crafted, thoroughly tested, clean and convenient interface between components
A
and B
, you may prefer to postpone messing in B
while you're polishing changes roughly drafted in A
, expecting that it will take less effort to integrate after interface at A
side gets clean back again.
In cases like this release dependencies allow you to totally isolate dependent component. You don't need to worry about component B
at all, until you are done with A
and modify dependency in B
to refer desired release. Snapshot dependencies can not offer anything like this: if changes made in A
break dependent component, you'll have to put an effort into bringing things back to shape.
Now, let's see how above applies in your case,
- unrelated projects
- each team working in a separate working branch
- split into multiple teams
All of the above whispers, says, cries that team is moving in a direction allowing more independent, more isolated work on the components of the system. So that John working on a project A
, Paul working on B
, George working on C
and Ringo working on D
have a leeway in planning and implementing changes within these components without permanently having to look at what happens in other components.
Now, let's look from above perspective at "dependencies between snapshot builds that each team produces". The way how Maven works, this would mean a huge step back into what team is supposed to move away from. the very moment John makes an intermittent change in A
and builds a snapshot, Maven immediately picks that snapshot and "broadcasts" it into projects of Paul, George and Ringo!
Now, three guys working in other projects have to adapt to changes made by John and, if these changes cause some serious trouble in other projects, most likely John will have to break his flow and urgently adapt their project to... oh by the way to what is he going to adapt? Paul, George and Ringo, they all work like John, their projects are permanently changing, are they supposed to explain to John what exactly he needs to take into account for today, and what he possibly will have to account for tomorrow?
You see, if team is supposed to move to more independent development of different components / projects, using snapshot dependencies essentially totally breaks this movement and returns you back to the days of monolithic approach.
If you want to keep moving to stronger separated components / projects, you better have to define "communication points" at which these projects would "declare" their readiness / obligation to integrate with others. In Maven, releases naturally serve this purpose.
Maven releases provide stable, fixed "checkpoints" allowing project developer to safely communicate with outer world.
- Release 2.15.23 is most recent one ready to be integrated; we no longer support / accept bug reports against releases earlier than 2.14.999; releases 2.15.24 and later ones currently suffer from a critical issue and are by no means intended for integration until further notice.
Worth stressing that release dependencies denote stable "checkpoints" between components, not between people. Whether components are maintained by separate developers or not isn't really relevant.
Even if you have, say, John working in both components A
and B
or maybe John and Paul together working on these two components, it still makes sense to have release dependencies, to allow programmer focus on work in currently chosen component, without being permanently distracted with worries about how this could impact another.
Given above, you also need to decide between teams how exactly are you going to schedule releases to make integration as smooth as possible. Here your options are really broad. A natural "schedule" that comes to mind is that each team decides when they're ready to offer a "checkpoint" of their work for other teams to integrate.
However natural ad-hoc releases sound "from within" a single team, if you look at it from the perspective of other teams, you may find that they would prefer to have a more regular way to get to "integration checkpoints" - from this perspective, you may wish to consider some predictable ways to "promote" component updates for other teams attention - monthly, or weekly, or maybe daily releases.
Now that your system became more complicated, specifics and purpose of snapshot dependencies are worth taking a closer look at. You can find a pretty decent explanation of this in Maven: The Complete Reference at Sonatype (bold font in below quote is mine):
...when you deploy a snapshot, you are not making a release of a software component; you are releasing a snapshot of a component at a specific time.
Why would you use this? SNAPSHOT versions are used for projects under active development. If your project depends on a software component that is under active development, you can depend on a SNAPSHOT release, and Maven will periodically attempt to download the latest snapshot from a repository when you run a build. Similarly, if the next release of your system is going to have a version "1.4", your project would have a version "1.4-SNAPSHOT" until it was formally released...
If a project depends on a SNAPSHOT, it is not stable as the dependencies may change over time... SNAPSHOT versions are for development only...
As you can see, above stresses temporary, intermittent, unstable nature of snapshot dependencies and limits their applicability to times of "active development". In your case, you can think of temporarily switching to snapshot dependency when you need to do series of closely correlated, synchronized, tightly coupled changes in different components. After this "active" phase is over, you can do "checkpoint" releases of involved components and switch back to release dependencies.
Note by the way that if you discover that switching to snapshot dependency happens too often, this might indicate a need to rethink your design. You may think of ways to better isolate components, or of opposite, that is, of "merging" previously separate components back into monolithic, synchronously developed and released module.