Search code examples
architecturemicroservicessemantic-versioning

SemVer and Microservices


Are there any best practices/patterns for applying SemVer in a microservice'd product? Should there be SemVer for each microservice, and SemVer for the overall product?

Example- I have a product called SuperDatabase with 3 microservices called SuperDatabaseCore, SuperDatabaseReports, and SuperDatabaseSearch.

Initial Release: SuperDatabase v1.0.0 SuperDatabaseCore v1.0.0 SuperDatabaseReports v1.0.0 SuperDatabaseSearch v1.0.0

Minor Update to Report: SuperDatabaseReport v1.1.0

Should the product be SuperDatabase v1.1.0 now?

What if later there is a patch to Search: SuperDatabaseSearch v1.0.1

Should the product versioning be changed again? Should the product version be completely independent of the microservice? Should it use SemVer at all? Or should it not have any versioning?


Solution

  • I know this is a late response but I thought I would share it.

    We have a number of microservices and each has its own semver. We're using docker container to deploy and even to release to the client (we release the docker image). There is a manifest for the docker to specify what version of what microservice is included... this is a man-job because we need to pick the compatible versions. Our devops are planning to use kubernetes and I think it has a good dependency management.

    The version of the product (marketing version) is completely different. The development doesn't care about the marketing version... they bump up their version depending on overall major/minor changes. This is actually the version of the docker image we release.

    Back to microsevices, we are using a automatic versioning... so the developers have to add a changelog to a change-log file by specifying the type of their change and based on that the build process bumps up the version (whether it's minor, major or patch). And once the changes are merged into main branch, the branch automatically gets tagged with that version. So basically we release continuously.

    In terms of shared libraries, we are also following semver. We are taking the advantage of maven range versions to fetch latest compatible version and if there is a major version, that needs a developer involved to upgrade the dependent applications .

    There are also these two articles I found:

    using a core to plug microsevices in and having multiple concurrent instances

    === UPDATE

    This is an update to my answer. Since there are lots of changes going on in our development, it made it hard for the developers to provide the type of change (backward compatible bug fix, BC enhancement or non-backward compatible change). Imagine up to 10 merge a day for each repository (microservice) we would end up with a version like 125.5455.0 perhaps. So we've decided to abandone versioning for microservices in this way and to use git commit id as the version. It's unique, it's automatic. I know that seems a bit odd but I can't tell you how much this approach helped us in CI/CD automation and the release process.

    We create a version manifest that looks like this:

    microservice-one:
      imageTag: "49e6f0f164324a314a475f483fcd9bd98e0e08ab"
    microservice-two:
     imageTag: "57e272c44eb9dd6302617a3b5fe0baf82fa61617"
    microservice-three:
     imageTag: "004dea68c4d4121d77cc4742f6b5702d7307d510"
    

    But the version we deliver to the client is like v1.2.0 and this version is linked to the above version manifest which helps us to find the actual commit that we have delivered from. We tag all docker images with this commit id.