Releases Versioning
Problem Description
In order to implement continuous deliver we need the release process for our service to be as smooth as possible, one important part of it is automation.
Right now, the next version for all services at Ebury is determined manually at release time following a semantic versioning strategy, although this strategy works really well for libraries and APIs it does not add much value for services not exposing an internal API.
Even more determining the next version for a service automatically, following a semantic versioning strategy is not a trivial process from an automation perspective.
Background
Ebury is following a semantic versioning approach for both libraries and services, there are currently 3 use cases:
- Services not exposing internal APIs
- Services exposing internal APIs with automated generated libraries
- Services exposing internal APIs without automated generated libraries
- Standalone libraries
Services not exposing internal APIs
Services not exposing internal APIs but connecting to other services via Kafka or SQS, for this type of services using semantic versioning is not giving any real benefits.
Services exposing internal APIs without automated generated libraries
Some services (e.g BOS, FXS) are exposing internal APIs, we have libraries maintained manually to connect to those services.
The versions from the libraries and the services does not match, using semantic versioning for this type of services is not giving any real benefits
Services exposing internal APIs with automated generated libraries
Some services exposing internal APIs are using OpenAPI Generator to generate automatically a Python library that can be used to connect with them.
These services are following a semantic versioning approach, even more, the version used for automatic generated library is the same as the version of the service.
Standalone libraries
Libraries used to handle infrastructure, etc in which the library is not automatically generated from the service especification (e.g jenkins-devops)
For users of a library it's important to know whether they can upgrade to a newer version and expect their software to keep working as expected, for this reason it makes sense to use semantic versioning for both standalone libraries and services exposing internal APIs with automated generated libraries.
Solution
Services not exposing internal APIs
The preferred versioning mechanism for services not exposing an API will be calendar versioning, the versions will follow the pattern: YYYY.M.D-H.m.s-UTC-{ShortCommitHash}
As an example, for the following data:
- Date 2021/05/17
- Time 03:06:08
- Commit hash: 8235488
the result would be: 2021.5.17-3.6.8-UTC-8235488
NOTE: the SemVer specification does not allow for leading 0 on any of the numeric versions included
Automatic versioning following this format is trivial in most programming languages, which will allow us to get the benefits of automatic releases sooner and with low costs. The rationale for including this information is:
- We will be using the date and time to provide unique identifiers for each deployment, this will allow anybody troubleshooting any issues with a service to quickly realize when the release took place.
- Since dates and times are ordered, telling which release took place first is also trivial.
- The git commit hash will allow developers to easily correlate deployments with the code stored on version control.
Services exposing internal APIs without automated generated libraries
The preferred versioning mechanism for the service will be calendar versioning, the same as in Services not exposing internal APIs
Services exposing internal APIs with automated generated libraries
For users of a library it's important to know whether they can upgrade to a newer version and expect their software to keep working as expected, for this reason the preferred versioning mechanism for the autogenerated libraries will continue to be semantic versioning.
The preferred versioning mechanism for the service will be calendar versioning, the same as in Services not exposing internal APIs
The rationale to split the service and library versions is that there are multiple changes that could be performed on the service level (hotfix, refactoring, etc) that are not going to change the API specification, and thus should have no impact on the library version.
Standalone libraries
For users of a library it's important to know whether they can upgrade to a newer version and expect their software to keep working as expected, for this reason the preferred versioning mechanism for libraries will continue to be semantic versioning.
Alternatives
We could use semantic versioning for services as well but there is no benefit in doing so.
Caveats
N/A
Operation
Generating calendar version is trivial in most programming languages, to generate a version following the format described in this document we can do:
`date -u +%Y.%m.%d`-`date -u +%H.%M.%S`-UTC-`git rev-parse --short HEAD`
Security Impact
N/A
Performance Impact
Calendar versioning will allow services that are not currently taking advantage of semantic versioning to save time at release time because they will not need to decide which is the next version for the service, on top of that, calendar versions are trivial to generate so this will allow us to get the benefits of automatic releases sooner.
Developer Impact
For regular services, using calendar versioning will allow developers to go faster since creating a new version for a service will be straightforward, on top of that, automating the release process will be faster as well.
Data Consumer Impact
N/A
Deployment
After this RFC is merged teams can start using calendar versions following the defined standard to name their releases.
Dependencies
We will need to update the CAB documentation on Confluence to reflect the new way to name releases.