I need advice on how to version builds based on shared and separate codes at the same time. I have a gradle project with multiple flavors. Large part of the code is shared. Some parts are flavor specific. Depending on which flavor I target, the corresponding code gets included.

I currently use semantic versioning. v1.2.0 was released before introducing any flavors. Now, if I make a change to flavor A specific code, I could release it as 1.2.1. But I make a change to the shared code next time around, should all flavors be released as 1.2.2? This will cause some flavors to jump versions in the future.

On the other hand, if I use separate version numbers for each flavor, it will be difficult to track common changes just by versions. Each flavor will have its own fix version for a specific bug for example.

Alternatively, I could maintain a single internal version for the common code, and separate versions for each flavor that can go out of sync. Again, this would make it a bit cumbersome to keep track of common features and bug fixes.

What do you think is the best approach?

  • To be clear, are you saying you have shared code like a common library that supports multiple products, and those products all have different versions? Even if you have a core product with some customization for specific customers, the same approach can be taken there. Commented Sep 28, 2018 at 18:53
  • @BerinLoritsch I have a single library with shared and unshared code (flavor specific). The flavr code of the targeted flavor gets included with the shared code to build the library (aar in this case). The library has the final version.
    – black
    Commented Sep 28, 2018 at 19:31

3 Answers 3


It seems to me that you have shared library code that forms part of 1 or more products (flavors). Personally, would version the library code independently. For example, if your library code consists of 3 modules, each could be versioned independently following semantic versioning.

Each product could then declare which library code it uses and the version it's designed to work with. Each product would then also have it's own semantic version.

In this way you can develop each module independently whilst supporting different release cycles of the products.


I'll start out by saying that it's OK to skip versions. Microsoft did it when jumping from Windows 8 to Windows 10, it happened with Apple OS X. These days it's not uncommon to have jumps in numbers between releases.

I say that to say this: if you don't intend on changing how you build your library, just allow for jumps in versions and it's OK.

I would recommend splitting your shared code from your flavored code. You see examples of this in several libraries where you add support for different frameworks (flavors) in layers. For example:

  • Fantastico.Amazelib.Core -- all the common stuff
  • Fantastico.Amazelib.NInject -- add support for NInject framework
  • Fantastico.Amazelib.MicrosftDI -- add support for MS dependency injection

Etc. You should get the drift. With this arrangement, your core library might not change much, or it may change more often than the different flavors. That doesn't matter. You can version them independently and your users can take advantage of the upgrades when they choose.


A typical version is W.X.Y.Z

W = Major X = Minor Y = Flavor Z = Build

Maintain a trunk or master build which flavors merge into and common changes merge out to flavor versions.



Version, first build, second build

Trunk Flavor 1, first build etc

Trunk Flavor 2, first build etc.

This will allow you to identify what master/trunk version a flavor originated from.

If you needed to bump the master you would make it:, then all flavors that can from that master would be: etc.

If you merge trunk into any flavor the next build number represents the version that includes the trunk changes and vice versa back to trunk. Major/Minor/Flavor versions don't change on merges, just the build incremented as the merge is treated just like another other code change.

  • This isn't semver. Commented Sep 28, 2018 at 23:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.