LibrePCB Developers Documentation
|
This page describes how releases of LibrePCB are created and maintained.
The file format of workspaces, libraries and projects is a very central part of LibrePCB, see File Format Versioning for details how it's implemented and how we handle forward/backward compatibility.
For the application we use version numbers according semantic versioning (MAJOR.MINOR.PATCH, e.g. "1.2.3"). So every increment of the major number means a breaking change, which is a file format change in our case (we consider any file format change as breaking because we don't provide forward compatibility at all).
As the file format also needs a version number, we just use the application's major version as the file format version. For example the application version "1.2" has the file format "1", and "13.37.42" has file format "13". Please note the special case of 0.x versions where the second number denotes the major version, so the application version "0.1.2" has file format "0.1". This way, the file format can always be determined by the application's version number.
Given that versioning system, it's clear that any application with the same major version uses exactly the same file format. And for developers it's clear that when changing something in the file format, the application's major version must be incremented.
The application version is compiled into the binary with the preprocessor define APP_VERSION
and the file format version with the define FILE_FORMAT_VERSION
. Whether the file format is stable or not is controlled by the define FILE_FORMAT_STABLE
. See following chapters for details.
The continuous development happens on feature/bugfix branches (or pull requests), which are merged into the master
branch as soon as they are finished. However, to reduce the complexity of the development workflow, we only accept file format changes on the master
branch if we're working on the next major release! So if the next release is planned to be a minor or bugfix release, no file format changes shall be merged into master
. In practice this means that for example every 1-2 years there is a window of a few months where file format changes are accepted.
Although it is a bit awkward to hold back new features affecting the file format, this is much more efficient. We learned in the past that accepting file format changes at any time causes a lot of overhead and complexity.
Generally, releases shall be created directly on the master
branch, i.e. the release tag points to a commit on master
. However, if an urgent bugfix release is required but minor features implemented since the last release shall not be released yet, it is possible to create a release branch based on the last release with the new tag pointing to that release branch.
Note that no release other than the last one will be maintained. For example after releasing LibrePCB 1.2.3, no bugfix releases will be created for any previous release.
For every officially released version we create a GPG signed Git tag on the corresponding release commit. The tag name contains all three numbers of the application's version number. Examples: "0.1.0-rc1", "0.1.0", "1.2.0", "1.2.1"
Because (at least) the master
branch is unstable while working on the next major release, it's very dangerous for end users to work productively with this version (it could break projects etc.!). So we should warn users in that situation.
This is done by displaying warnings in the application's GUI. Their visibility is controlled by the preprocessor define FILE_FORMAT_STABLE
. It's set to 0
(warning visible) while working on the next major release, otherwise to 1
(warning disabled).
We use Transifex to translate LibrePCB into other languages. The resource librepcb.ts
always contains the strings from the latest commit on the master
branch. Translations are automatically checked into the repository LibrePCB/librepcb-i18n.
The librepcb-i18n
repository is included as a submodule in the main repository. Because translations change very often (and thus we would have to update the submodule very often), the submodule is not regularly updated (to avoid commit spam). It gets updated only when preparing a new release (important for packagers to get the correct translations).
The changelog is not checked into the repository because it would probably lead to confusion (add it to the master
branch, release branches or even both?). Instead, currently we use our blog to list the changes of every release.
Releases built by ourselves (Windows builds, installers, AppImage etc.) are published at https://download.librepcb.org, inclusive GPG signature. The website https://librepcb.org contains direct download links to the corresponding files.
Packages of package managers (e.g. APT, Flatpak, homebrew, ...) are updated by the corresponding package maintainers. Typically they clone the tag we released and then build the application from sources. Thanks to the translations checked into the release branches, package maintainers don't have to care about downloading translations from Transifex.
master
, add a commit to increment the application's major version and the file format version. In addition, set the define FILE_FORMAT_STABLE
to 0
.FILE_FORMAT_STABLE
is set to 1
!release-x.y.z
../dev/update_contributors.py
and commit (Message: Update AUTHORS.md).i18n
submodule and commit (Message: Update submodule "i18n").LIBREPCB_APP_VERSION
in CMakeLists.txt
(e.g. "0.1.0-rc1" or "0.1.1") and commit (Message: Bump version to X.Y.Z).share/metainfo/org.librepcb.LibrePCB.metainfo.xml
, commit (Message: Add X.Y.Z release notes to AppData XML) and push.master
(either by merging the PR or locally with merge commit [preferred] or fast-forward).LIBREPCB_APP_VERSION
(e.g. "0.1.0-rc1"). Use the message "LibrePCB <LIBREPCB_APP_VERSION>". Keep in mind that the tag must be signed and the version number must always have three numbers (i.e. "0.1.0" instead of "0.1")!master
(e.g. to "1.2.3-unstable" after releasing "1.2.2"), commit and push.