After working for more than a year developing and managing releases of platform built of microservices I figured repeatable process that can be automated. More on this below.
Let's split release process into 3 phases:
- understanding what should go out in release
- preparing changes
- pushing them in the wild
We're using Git and A successful Git branching model, which is rather questionable, I prefer FeatureBranch workflow, but that's a different story.
First phase: Understanding of what should go out
In our issue tracking tool, stories that should go out are marked as "Ready for Merge" (we use jira.com but it doesn't matter). I grab list of stories, run simple script that look like this mia review --cards=MIA-1022 MIA-988 MIA-1097 MIA-688
. The output is a list of services affected by these stories, so that you don't need to go and manually review every story to see services affected, example output looks like this:
[+] [2/16] user-service: MIA-1198, MIA-2023
[+] [6/16] checkout-service: MIA-1097 MIA-688
[+] [7/16] inventory-service: MIA-1022 MIA-988, MIA-1198, MIA-2023
Second phase: Preparing changes
Semi-manual process for me, because in some cases the "in-progress" stories from develop branch need to be ignored and can't go to master. But in most cases I can merge develop straight to master, and when I can, I have another command: mia merge --services=user checkout inventory
. This command goes over specified services and creates Pull Requests to merge develop branch to master and prints out links to pull requests.
Third phase: pushing changes in the wild
To push something to staging environment and then to production, service has to have a version. Empirically we figured that if you do semver for services, and moreover if you do it only for services that have changes it'll be hard to understand the "latest". Because what if pace of development of checkout service significantly higher then inventory service, you end up with something like v3.3.6 in checkout and v1.2.0 in inventory.
So to solve this: we're tagging all services with same tag version composed of the year, month, day and rc version. Example: r2015052601, and then we also have a command mia diff r2015052401 r2015052601
, which searches for specified tag in every service and prints a diff of changes between 2 tags. Part of me thinks that tagging all services with same version violates one of the principles of microservices architecture, but for us right now it solves major pain point of tags compatibility and understanding what's latest, because you can assume that latest tag exists everywhere, and if there were no changes, then there were no changes.
Thanks