The growing trend towards Agile development, where projects are in a continuous cycle of building, testing, and deploying, has led, unsurprisingly, to an increase in the frequency of releases. Furthermore, the move towards Software as a Service (SaaS), where software products remain hosted and in the control of the companies that distribute them (rather than fully installed on the customer's machine), allows software developers to minimize the friction or impact of implementing changes and new releases. As a result, the increased frequency and integration of releases has led to a new field of release management that aims to streamline this process and a new generation of tools are becoming available to automate the release process.
Release management is thus the process of managing, planning, scheduling and controlling a software build through different stages and environments; including testing and deploying software releases.
Releases are numbered according to whether they are major releases or minor changes.
For example, the software OS 10.13.2 is the 2nd minor revision of the 13th major version of the product known as OS 10.
Commercial software companies usually charge a fee for new major releases, but give away free minor releases for existing customers.
Best practices in industry have been generalized and drafted into a set of recommendations named Semantic Versioning. While this system of versioning is not universal, it provides a decent baseline for thinking about version numbers.
In semantic versioning, version numbers take the form of X.Y.Z:
- X is the major version
- Y is the minor version
- Z is the patch version.
Semantic versioning v2.0.0 includes 12 rules for version numbering. I am including the first 8, which are the general rules most projects follow:
- Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it should be precise and comprehensive.
- A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor version, and Z is the patch version. Each element MUST increase numerically. For instance: 1.9.0 -> 1.10.0 -> 1.11.0.
- Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications MUST be released as a new version.
- Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
- Version 1.0.0 defines the public API. The way in which the version number is incremented after this release is dependent on this public API and how it changes.
- Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.
- Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes. Patch version MUST be reset to 0 when minor version is incremented.
- Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY include minor and patch level changes. Patch and minor version MUST be reset to 0 when major version is incremented.
A software product release may contain:
- configuration files defining how the release should be configured for particular installations
- data files, such as error messages and localized content for multiple languages
- an installation program to help install the system on its target environment
- documentation describing the system
- marketing materials and product packaging that have been specifically designed for the release
Companies often are under a lot of pressure to release software products at 'the right time'. Determine when is the right time is an art more than a science, although it is becoming heavility influenced by market competitive anlysis and predictive analytics. Factors that may influence the decision of when to release a product include:
- Competition - if a competitor has already released or will imminently release a similar product, customers may expect a similar update with similar features
- Marketing - partnerships or deals with other organizations or media may dictate when a product can be released
- Dependencies - new versions of platforms that existing software depends on, such as operating systems, may require new releases of a product for it to stay functional on the updated platform
- Bug fixes - major flaws in a product may require extensive changes in a new version. Small changes may be able to be 'patched' without a full release.
The growing fields of data science and machine learning have led to a practice named predictive analytics, which seeks to use past data to predict future events. For example, to predict when Apple should launch a new product to market. One can expect more of this machine-data-driven market analysis in the future.
Release and source control
In a trunk-based work flow, the code in the trunk is in a constant state of readiness to be deployed. This means, code can be released at any point from the trunk. However, specific releases are given release numbers - these are typically given as tags, labels which mark specific points in the history of the project. Tags are nothing but shortcuts to the code as it was at a specific point in a particular branch.
For example, the following command will create a tag on the currently checked-out branch, labeling it as release version 1.0:
git tag v1.0
Or alternatively, give an annotated tag, including a message:
git tag -a v1.1 -m "version 1.1 of the coffee grind future fineness predictive algorithm"
To view a list of all tags on the branch:
To view details of a specific tag:
git show v1.1
To push the release to an upstream remote repository, such as GitHub:
git push origin v1.1
Delete a tag from the local repository:
git tag -d v1.1
Delete a tag from the upstream remote repository:
git push origin -d v1.1
To checkout code as it was at a specific point in time into a new branch, specify the tag name that you want to check out, and the branch name you want to put it in:
git checkout -b <branch name> <tag name>
GitHub release management
GitHub has a graphical user interface tool to simplify the process of creating release tags with Git.
- Software Engineering, 10th edition, by Ian Sommerville. Chapter 25.4 - Configuration management / release management
- Git Tags - what, why, when and how, by Raghav Pal - https://www.youtube.com/watch?v=govmXpDGLpo
- Release deployment and management, by Purushothaman D - https://www.youtube.com/watch?v=JGwLHvY7Ohg