Skip to content
Snippets Groups Projects
versioning.md 6.64 KiB
Newer Older
+++
date = "2019-11-15"
weight = 100

title = "Versioning"

aliases = [
    "/architecture/binary_package_versioning/",
    "/guidelines/versioning/",
    "/old-wiki/Guidelines/Versioning",
    "/old-wiki/Build_and_Integration_infrastructure_documentation"
]
+++

It is important to properly
[version](https://en.wikipedia.org/wiki/Software_versioning) software to enable
software changes and compatibility of components to be tracked, as well as to
aid with bug tracking and the application of updates. To achieve this, it is
important that we effectively version each source module, binary package and
release.

# Module Versioning

Module versioning differs for libraries and applications: libraries need a
libtool version specified in addition to their package version.  Applications
just have a package version.

## Libtool versioning

Libraries have two version numbers: a libtool version which tracks ABI
backwards compatibility, and a [package version](#package-versioning) which
tracks feature changes.  These are normally incremented in synchronisation, but
should be kept separate because ABI backwards compatibility is not necessarily
related to feature changes or bug fixes. Furthermore, the two version numbers
have different semantics, and cannot be automatically generated from each
other.

A good overview of libtool versioning, and the differences from package
versioning, is given in the
[Autotools Mythbuster](https://autotools.io/libtool/version.html).

To update the libtool version, follow the algorithm given in the comments
below. This is a typical `configure.ac` snippet for setting up libtool
versioning:

```
# Before making a release, the LT_VERSION string should be modified. The
# string is of the form c:r:a. Follow these instructions sequentially:
#   1. If the library source code has changed at all since the last update, then
#      increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
#   2. If any interfaces have been added, removed, or changed since the last
#      update, increment current, and set revision to 0.
#   3. If any interfaces have been added since the last public release, then
#      increment age.
#   4. If any interfaces have been removed or changed since the last public
#      release, then set age to 0.
AC_SUBST([LT_VERSION],[0:0:0])
```

The following snippet can be used in a `Makefile.am` to pass that version info
to libtool:

```
my_library_la_LDFLAGS = -version-info $(LT_VERSION)
```

If a package contains more than one library, it should usually have a separate
libtool version for each one.

The standard process for making a release of a module increments the libtool
version (if the module is a library) and the package version immediately before
release. This is called pre-release incrementing.

The use of pre-release increment for libtool versions means that they are only
incremented once for all ABI changes in a release. Some projects use
post-release increment for package versions to ensure that the package version
number is not outdated (i.e. still equal to the previous release) during the
development cycle; we achieve this by altering the version number automatically
in
[the build-snapshot script](https://gitlab.apertis.org/pkg/target/apertis-customizations/blob/apertis/v2020dev0/development/build-snapshot)
instead.

## Package versioning

The package version number for a library is that passed to `AC_INIT()`, and the
one which is typically known as the project’s version number.  For example, the
Debian package for a library will use the library’s package version.

Versions of packages developed for Apertis have the form `x.y.z` and are
updated according to the following rules:

- `x` starts at 0, and increments when there is a major compatibility break.
  Libraries with different major versions should usually be
  [parallel-installable]( {{< ref "module_setup.md#parallel-installability" >}} ).
- `y` is the Apertis branch year and month as a single 4-digit number, for
  instance `1706`.
- `z` is 0 for the first release to each branch, and goes up for each release
  (whether it is a feature release or bugfix-only).

# Understanding Binary Build Suffixes

For every binary release (*Developer, Preview, Product*), we add a build suffix
string to the packages, which relates to the release name of Apertis.  The
build suffix gets added to every built .deb package. Having a build suffix
helps determine which Apertis release the .deb package was built for.

The suffix string is constructed of: `b<Release_Name>b<B_CNT>`.
- The initial `b` is for backward compatibility ensuring the new suffix string
  can work well together with older release packages.
- `<Release_Name>` refers to the Apertis release's name.
- `b<B_CNT>` refers to being a binary build along with the build count.

The build count is incremented each time the package is built, regardless of
whether the source has changed.

For example, for the Apertis Developer Release `v2020dev0` we add the string
`bv2020dev0b1` to the project configuration on OBS when the package is first
built.  Similarly, for an Apertis Product Release of `v2019.0` we add the
string `bv2019.0b2` to the project configuration on OBS when it is built for
the second time with no source change.

# Product Point Release Versioning

A product point release rolls the packages previously released in the update and
security repositories into the stable branch. It is required to ensure that the
packages in the new point release have a higher version than the binary package
in the updates or security repositories, it is thus necessary to include the point
releases numbering (e.g. `v2020.1`, `v2020.2`) in the build suffix.

For example, during the initial release of the v2020 release, the build suffix
was `bv2020.0b<B_CNT>`. The same build suffix is inherited by the updates and
security sub-repositories during this time period. Before doing a new point
release *v2020.1*, the build suffix of the main repositories
(`apertis:v2020:target`, `apertis:v2020:development`, `apertis:v2020:sdk`,
`apertis:v2020:hmi` etc) is set to `vb2020.1b<B_CNT>`.

Once this step has been taken, changes previously commited to Apertis update
and security branches (such as `apertis/v2020-updates` and
`apertis/v2020-security`) are merged into the main release branch
(`apertis/v2020`), thus triggering a build and generation of a package with the
required point release suffix. This ensures that the packages synced from the
updates and security sub-repositories have higher versions than packages from
the updates and security sub-repositories. Once the merge has been completed,
the equivalent packages in the update and security branches are purged to allow
these branches to be used for following updates and security fixes to the new
point release.