# Releases

## Versioning

Every release of Xournal++ is tagged with a unique incrementing version. In the history of the project, two changes to the versioning scheme happened. Be careful when trying to automatically parse older versions.
The current versioning scheme adheres to the rules of [Debian upstream_version](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version).

### Main Version

We follow the common versioning scheme of major, minor and patch versions in this order, separated by dots.

The version string therefore has the following format:

```
[0-9]+\.[0-9]+\.[0-9]+
```

We do NOT adhere to semantic versioning, as it is primarily meant for libraries and is more confusing to normal users than it is helpful.
To help you understand when we use what version increment, use these rules:

- A major version bump happens when we introduce a change with a very high impact to many users. For example a major redesign of the GUI or the introduction of a new file format as the default format.
- A minor version bump happens whenever we introduce new features
- A patch version bump happens whenever we introduce fixes to already implemented features. This may include minor changes to existing features as well.

Whenever a bump of the major version happens, minor and patch versions are reset to `0`. Equally the patch version is reset to `0` when the minor version is bumped.

### Version Suffix

The main version string may be followed by a suffix. This suffix is used to describe unreleased versions and hotfixes.

The suffix may only start with one of the two characters `+` or `~`. These characters hold special meaning:

- `+` denotes a version that is based on top of the main version (is newer)
- `~` denotes a version that predates the main version (is older)

The suffix may only contain alphanumerics, `+`, `~`, `-` and `.`.

We mainly use suffixes to specify development versions. Our main development branch (`master`) has a permanent suffix `+dev` and as main version the last released version of Xournal++. This specifies that the current commit of the main development branch is based on the last release of Xournal++, but may contain any number of changes.

When we start our release process, we branch off a release branch. At this point of time it is clear what changes we include in the release and we can use the above rules to determine the correct version. From this point on we will change the main version string to this new version and use the suffix `~dev`. This describes our intent of working towards this release.

## Branching Strategy

Our branching model knows five types of branches:

- The main development branch (`master`) used for merging feature branches and hosting the newest state of Xournal++.
- Release branches (`release-*`) exist for preparing a release. This type of branches is branched off from the main development branch and will from that point on only receive bug fixes for the current version of this branch. Only the patch level may be bumped on such branches. When the release is ready, it is tagged on this branch and then merged back to the main development branch.
- Hotfix branches (`hotfix-*`) originate from the tagged commit of a released version and facilitate the development of a hotfix. When the hotfix is ready for release, it will be tagged and merged back into the main development branch.
- Feature branches (`feature-*`) are commonly used for Pull Requests with new features. Such branches are always merged into the main development branch.
- Bugfix branches (`bugfix-*`) are used for Pull Requests with a bugfix for a maintained release or the current development version. Depending on their target they must be merged into the appropriate branch.

## Helper Script

To help with the task of versioning, we provide a helper script, that does most of the work for you. You can find the script at `scripts/release_helper.sh`.

### Preparing a new minor/major release
The starting point of a new minor/major release is always the main development branch. You may use `release_helper.sh prepare <version>` to prepare the release. `<version>` Shall be replaced with the appropriate version. Be aware that the patch version must be `0`.

The script will:

1. Create a release branch
2. Check the new branch out
3. Apply the supplied version to all relevant files suffixed by `~dev`.

Whatever version suffix you choose, will be appended by `~dev` to signify that this is not yet the release version but development progresses towards this release.

### Preparing a hotfix
The starting point of a hotfix release is the tagged commit of the release this hotfix is based upon. You must check out this release and then call `release_helper.sh prepare <version><+suffix>` where the version equals the currently checked out version and the chosen suffix. The suffix must start with a `+` as only hotfixes based on top of this version are allowed.

The script will:

1. Create a hotfix branch
2. Check the new branch out
3. Apply the supplied version to all relevant files suffixed by `~dev`.

### Publishing a release
Publishing a release can only happen on a release branch or a hotfix branch. It can be triggered by `release_helper.sh publish` and will initiate the process of publishing the release.

The script will:

1. Remove the `~dev` suffix (and leave any other suffix supplied by the user)
2. Update the changelogs to signify the release of this version
3. Tag the release
4. Proposal to merge the release back to the main development branch

During the merge it is imperative that the instructions of the script are followed stringently to not confuse our versioning scheme.


## Release checklist

To summarize all of the above information, the following checklist should be
followed when publishing a release:

* [ ] Checkout the release branch.
* [ ] Update `CHANGELOG.md` with the latest changes.
  * You may want to open a PR so that other maintainers can review the
    changelog.
  * Run `git log --graph <last_version_tag>..HEAD` to get a quick
    summary of the logs.
  * To correlate commits with PRs, you can go to
    `https://github.com/xournalpp/xournalpp/commit/<commit_hash>`. The PR number
    will be displayed next to the author information.
* [ ] Open a new pull request to allow all maintainers to review the release and
      confirm that it has the correct contents. This should consist of two
      commits in total:
  * [ ] Summarize the changes in `debian/changelog`, and create a commit. Note
        that this summary can and should be reused for the GitHub release
        description later.
  * [ ] Then run `scripts/release_helper.sh publish` to create the release
        commit and tag the commit. This will also automatically create a commit
        bumping to the next development version.
  * [ ] Squash the `debian/changelog` commit and the release commit into a
        single commit. Do _not_ squash the version bump commit. This is needed
        so that Debian helpers and the unofficial PPAs can pick up releases
        correctly.
  * [ ] Retag the release commit with `git tag -f <version_number> <commit>`
  * [ ] **Do not merge using GitHub's web interface.** To avoid accidental
        merges, mark the PR as draft.
* [ ] Push the release to GitHub:
  * [ ] Directly push the HEAD commit of the PR to the release branch. **Do not
        create a merge commit, the commit should be fast-forwarded.**
  * [ ] Push the tag.
* [ ] A tag push should trigger a run of the "Release" pipeline on Azure
      Pipelines (not to be confused with the "Releases" tab); ensure that it
      succeeds.
  * [ ] Check that the "Release" pipeline succeeds.
  * [ ] Go to "Releases" tab (not the pipeline) and trigger a manual deployment
        with "Create Release".
  * [ ] Check that the deployment successfully creates a GitHub release draft.
* [ ] Last checks on the GitHub release draft
  * [ ] Update the release description.
  * [ ] Test the release draft artifacts for obvious issues.
  * [ ] Publish the release.
* [ ] Check that the [FlatHub release][flathub] is built successfully.
* [ ] Update the version on [the website repository][website].
* [ ] After the release is created, merge back the release branch into `master`.


[flathub]: https://github.com/flathub/com.github.xournalpp.xournalpp
[website]: https://github.com/xournalpp/xournalpp.github.io
