2020-07-01 17:26:49 +03:00
|
|
|
---
|
|
|
|
layout: developer-doc
|
|
|
|
title: Release Policy
|
|
|
|
category: distribution
|
|
|
|
tags: [distribution, release, release-policy, policy]
|
|
|
|
order: 3
|
|
|
|
---
|
|
|
|
|
|
|
|
# Release Policy
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
As an open-source project and programming language, it is incredibly important
|
|
|
|
that we have a well-defined release policy. This document defines said policy.
|
|
|
|
|
2020-09-14 12:05:37 +03:00
|
|
|
> **Once a release has been made it is immutable. The release should only ever
|
|
|
|
> be edited to mark it as broken. Nothing else should ever be changed.**
|
|
|
|
>
|
|
|
|
> **No two release workflows can be running at once, to avoid race conditions
|
|
|
|
> since releases
|
|
|
|
> [must update files in S3](fallback-launcher-release-infrastructure.md#updating-the-release-list).
|
|
|
|
> Make sure that tags which trigger release builds are pushed sequentially, only
|
|
|
|
> pushing the next one after the previous build has finished.**
|
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
|
|
|
|
|
|
|
- [Versioning](#versioning)
|
2020-07-08 16:54:41 +03:00
|
|
|
- [Launcher Versioning](#launcher-versioning)
|
2020-07-01 17:26:49 +03:00
|
|
|
- [Release Branches](#release-branches)
|
|
|
|
- [Release Workflow](#release-workflow)
|
2020-07-08 16:54:41 +03:00
|
|
|
- [Tag Naming](#tag-naming)
|
2020-09-09 16:37:26 +03:00
|
|
|
- [Manifest Files](#manifest-files)
|
|
|
|
- [Breaking Changes to Launcher Upgrade](#breaking-changes-to-launcher-upgrade)
|
2020-07-08 16:54:41 +03:00
|
|
|
- [GitHub Releases](#github-releases)
|
|
|
|
- [Release Notes](#release-notes)
|
2020-07-01 17:26:49 +03:00
|
|
|
- [Version Support](#version-support)
|
|
|
|
- [Working on the Current Release](#working-on-the-current-release)
|
|
|
|
- [Backporting Fixes](#backporting-fixes)
|
|
|
|
|
|
|
|
<!-- /MarkdownTOC -->
|
|
|
|
|
|
|
|
## Versioning
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
Releases of Enso are versioned using [semantic versioning](https://semver.org).
|
|
|
|
Where `a.b.c-tag` is the version string, `a` is the major version, `b`, is the
|
|
|
|
minor version, `c` is the patch version, and `tag` is additional metadata, the
|
|
|
|
following hold:
|
|
|
|
|
|
|
|
- Breaking changes to language behaviour or the public API will result in a
|
|
|
|
major version increase.
|
|
|
|
- Addition of functionality in a backwards-compatible manner will result in a
|
|
|
|
minor version increase.
|
|
|
|
- Backwards-compatible bug fixes will result in a patch version increase.
|
|
|
|
- The tag will indicate pre-release or beta versions, and will increase when any
|
|
|
|
pre-release change is made. These are not intended to be stable.
|
|
|
|
|
2020-07-08 16:54:41 +03:00
|
|
|
### Launcher Versioning
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-08 16:54:41 +03:00
|
|
|
The launcher is released alongside Enso releases, so the launcher version is
|
|
|
|
tied to the Enso version that it is released with.
|
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
## Release Branches
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
A release branch in the Enso repository is a branch prefixed with `release/`.
|
|
|
|
Release branches obey the following rules:
|
|
|
|
|
|
|
|
- One release branch exists per major version, and is named `release/n.x`, where
|
|
|
|
`n` is the major version, and the rest is literal.
|
|
|
|
- A release branch must contain _tags_ corresponding to released versions of
|
|
|
|
Enso. Once a release has been made, no further changes may be made to that
|
|
|
|
release.
|
2021-01-05 17:14:08 +03:00
|
|
|
- A tagged release must contain a `RELEASES.md` file that describes the changes
|
2020-07-01 17:26:49 +03:00
|
|
|
contained in that release.
|
|
|
|
|
|
|
|
It should be noted that general development still takes place on the `main`
|
|
|
|
branch of the repository.
|
|
|
|
|
|
|
|
## Release Workflow
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
Cutting a release for Enso proceeds as follows:
|
|
|
|
|
|
|
|
1. If no release branch exists for the current major version, one should be
|
|
|
|
created.
|
2021-04-28 17:50:55 +03:00
|
|
|
2. Create a branch called `wip/<initials/release-bump`. On this branch, ensure
|
|
|
|
that the release notes are up to date in `RELEASES.md` (follow the existing
|
|
|
|
format), and that the new version number has been set in `build.sbt`. This
|
|
|
|
version should _not_ contain `SNAPSHOT`.
|
|
|
|
3. Open a PR for this branch into `main`.
|
|
|
|
4. Once the changes have been reviewed, merge the PR into main (getting commit
|
|
|
|
hash `xxxxxxx`). The message should be `Prepare for the $version release`.
|
|
|
|
5. Immediately push a commit to `main` that updates the version in `build.sbt`
|
|
|
|
to the new snapshot version. If unclear, bump the patch version by one and
|
|
|
|
append `-SNAPSHOT` (e.g. `0.2.10` becomes `0.2.11-SNAPSHOT`). The message
|
|
|
|
should be `Bump the snapshot version`.
|
|
|
|
6. Find the commit hash of the last "Bump the snapshot version" commit. Let's
|
|
|
|
say this is `yyyyyyy`.
|
|
|
|
7. Run a `rebase --onto` the release branch from the `yyyyyyy` commit to the
|
|
|
|
`xxxxxxx` commit. For example:
|
|
|
|
|
|
|
|
```
|
|
|
|
git rebase --onto origin/release/0.x yyyyyyy~1 xxxxxxx
|
|
|
|
```
|
|
|
|
|
|
|
|
8. This will put you into a "detached HEAD" state at commit `zzzzzzz`, so you
|
|
|
|
need to make a new branch: `git branch release-update zzzzzzz`
|
|
|
|
9. This new branch is a fast-forward merge away from the release branch. Check
|
|
|
|
out the release branch and then fast-forward merge `release-update` into it.
|
|
|
|
For example:
|
|
|
|
|
|
|
|
```
|
|
|
|
git checkout release/0.x
|
|
|
|
git merge --ff-only release-update
|
|
|
|
```
|
|
|
|
|
|
|
|
10. As long as the fast-forward proceeds cleanly, you can push the updated
|
|
|
|
release branch to the origin.
|
|
|
|
11. Create a tag for the commit at the HEAD of the release branch. It should be
|
|
|
|
named as above. For example:
|
|
|
|
|
|
|
|
```
|
|
|
|
git tag --sign enso-0.2.11
|
|
|
|
```
|
|
|
|
|
|
|
|
12. Push the tag to the remote. This will start the release build.
|
|
|
|
13. CI will create a draft release for this tag, as well as build and upload the
|
|
|
|
appropriate artefacts. **Do not** create a release for this tag manually.
|
|
|
|
14. The release notes for the version being released should be copied from the
|
|
|
|
new section in `RELEASES.md` into the GitHub release description with the
|
|
|
|
line breaks removed.
|
|
|
|
15. The title of the release should be `Enso Engine <version>` (e.g.
|
|
|
|
`Enso Engine 0.2.11`).
|
|
|
|
16. The release must be verified by at least one member of the engine team and
|
|
|
|
the QA team.
|
|
|
|
17. Once verification has been performed, the release can be published. It
|
|
|
|
should _not_ be a pre-releases as we reserve these for nightly builds.
|
2020-07-01 17:26:49 +03:00
|
|
|
|
|
|
|
### Tag Naming
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
Tags for releases are named as follows `enso-version`, where `version` is the
|
|
|
|
semver string (see [versioning](#versioning)) representing the version being
|
|
|
|
released.
|
|
|
|
|
2020-09-09 16:37:26 +03:00
|
|
|
### Manifest Files
|
2020-07-01 17:26:49 +03:00
|
|
|
|
2021-01-05 17:14:08 +03:00
|
|
|
Manifest files are used to describe metadata about various releases for use by
|
|
|
|
the Enso tooling.
|
|
|
|
|
2020-09-09 16:37:26 +03:00
|
|
|
#### Engine Manifest
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-21 11:14:26 +03:00
|
|
|
Each GitHub release contains an asset named `manifest.yaml` which is a YAML file
|
|
|
|
containing metadata regarding the release. The manifest is also included in the
|
|
|
|
root of an Enso version package. It has at least the following fields:
|
2020-07-08 16:54:41 +03:00
|
|
|
|
|
|
|
- `minimum-launcher-version` - specifies the minimum version of the launcher
|
|
|
|
that should be used with this release of Enso,
|
2020-12-16 14:34:33 +03:00
|
|
|
- `minimum-project-manager-version` - specifies the minimum version of the
|
|
|
|
project manager that should be used with this release of Enso; currently it is
|
|
|
|
the same as the launcher version but this may change in the future,
|
2020-07-08 16:54:41 +03:00
|
|
|
- `graal-vm-version` - specifies the exact version of GraalVM that should be
|
|
|
|
used with this release of Enso,
|
|
|
|
- `graal-java-version` - as GraalVM versions may have different variants for
|
|
|
|
different Java versions, this specifies which variant to use.
|
|
|
|
|
2020-12-16 14:34:33 +03:00
|
|
|
The minimum launcher and project manager versions are kept as separate fields,
|
|
|
|
because at some point the same runtime version management logic may be
|
|
|
|
associated with different versions of these components.
|
|
|
|
|
2020-08-19 15:24:31 +03:00
|
|
|
It can also contain the following additional fields:
|
|
|
|
|
|
|
|
- `jvm-options` - specifies a list of options that should be passed to the JVM
|
|
|
|
running the engine. These options can be used to fine-tune version specific
|
|
|
|
optimization settings etc. Each option must have a key called `value` which
|
|
|
|
specifies what option should be passed. That value can include a variable
|
|
|
|
`$enginePackagePath` which is substituted with the absolute path to the root
|
|
|
|
of the engine package that is being launched. Optionally, the option may
|
|
|
|
define `os` which will restrict this option only to the provided operating
|
|
|
|
system. Possible `os` values are `linux`, `macos` and `windows`.
|
2020-09-01 13:03:48 +03:00
|
|
|
- `broken` - can be set to `true` to mark this release as broken. This field is
|
|
|
|
never set in a release. Instead, when the launcher is installing a release
|
|
|
|
marked as broken using the `broken` file, it adds this property to the
|
|
|
|
manifest to preserve that information.
|
2020-08-19 15:24:31 +03:00
|
|
|
|
2020-07-08 16:54:41 +03:00
|
|
|
For example:
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-08 16:54:41 +03:00
|
|
|
```yaml
|
2020-07-10 13:57:42 +03:00
|
|
|
minimum-launcher-version: 0.0.1
|
2020-12-16 14:34:33 +03:00
|
|
|
minimum-project-manager-version: 0.0.1
|
2020-08-19 15:24:31 +03:00
|
|
|
jvm-options:
|
|
|
|
- value: "-Dpolyglot.engine.IterativePartialEscape=true"
|
|
|
|
- value: "-Dtruffle.class.path.append=$enginePackagePath\\component\\runtime.jar"
|
|
|
|
os: "windows"
|
|
|
|
- value: "-Dtruffle.class.path.append=$enginePackagePath/component/runtime.jar"
|
|
|
|
os: "linux"
|
|
|
|
- value: "-Dtruffle.class.path.append=$enginePackagePath/component/runtime.jar"
|
|
|
|
os: "macos"
|
2020-12-16 14:34:33 +03:00
|
|
|
graal-vm-version: 20.2.0
|
|
|
|
graal-java-version: 11
|
2020-07-08 16:54:41 +03:00
|
|
|
```
|
|
|
|
|
2020-07-10 13:57:42 +03:00
|
|
|
The `minimum-launcher-version` should be updated whenever a new version of Enso
|
|
|
|
introduces changes that require a more recent launcher version. This value is
|
|
|
|
stored in
|
2020-07-21 11:14:26 +03:00
|
|
|
[`distribution/manifest.template.yaml`](../../distribution/manifest.template.yaml)
|
2020-07-10 13:57:42 +03:00
|
|
|
and other values are added to this template at build time.
|
|
|
|
|
2020-09-09 16:37:26 +03:00
|
|
|
#### Launcher Manifest
|
|
|
|
|
|
|
|
Additionally, each release should contain an asset named
|
|
|
|
`launcher-manifest.yaml` which contains launcher-specific release metadata.
|
|
|
|
|
|
|
|
It contains the following fields:
|
|
|
|
|
|
|
|
- `minimum-version-for-upgrade` - specifies the minimum version of the launcher
|
|
|
|
that is allowed to upgrade to this launcher version. If a launcher is older
|
|
|
|
than the version specified here it must perform the upgrade in steps, first
|
|
|
|
upgrading to an older version newer than `minimum-version-for-upgrade` and
|
|
|
|
only then, using that version, to the target version. This logic ensures that
|
|
|
|
if a newer launcher version required custom upgrade logic not present in older
|
|
|
|
versions, the upgrade can still be performed by first upgrading to a newer
|
|
|
|
version that does not require the new logic but knows about it and continuing
|
|
|
|
the upgrade with that knowledge.
|
|
|
|
- `files-to-copy` - a list of files that should be copied into the
|
|
|
|
distribution's data root. This may include the `README` and similar files, so
|
|
|
|
that after the upgrade these additional files are also up-to-date. These files
|
|
|
|
are treated as non-essential, i.e. an error when copying them will not cancel
|
|
|
|
the upgrade (but it should be reported).
|
|
|
|
- `directories-to-copy` - a list of directories that should be copied into the
|
|
|
|
distribution's data root. Acts similarly to `files-to-copy`.
|
|
|
|
|
|
|
|
A template manifest file, located in
|
|
|
|
[`distribution/launcher-manifest.yaml`](../../distribution/launcher-manifest.yaml),
|
|
|
|
is automatically copied to the release. If any new files or directories are
|
|
|
|
added or a breaking change to the upgrade mechanism is being made, this manifest
|
|
|
|
template must be updated accordingly.
|
|
|
|
|
|
|
|
### Breaking Changes to Launcher Upgrade
|
|
|
|
|
|
|
|
If at any point the launcher's upgrade mechanism needs an update, i.e.
|
|
|
|
additional logic must be added that was not present before, special action is
|
|
|
|
required.
|
|
|
|
|
|
|
|
First, the additional logic has to be implemented and a new launcher version
|
|
|
|
should be released which includes this additional logic, but does not require it
|
|
|
|
yet. Then, another version can be released that can depend on this new logic and
|
|
|
|
its `minimum-version-for-upgrade` has to be bumped to that previous version
|
|
|
|
which already includes new logic but does not depend on it.
|
|
|
|
|
|
|
|
This way, old launcher versions can first upgrade to a version that contains the
|
|
|
|
new logic (as it does not depend on it yet, the upgrade is possible) and using
|
|
|
|
that new version, upgrade to the target version that depends on that logic.
|
|
|
|
|
|
|
|
### GitHub Releases
|
|
|
|
|
|
|
|
A release is considered _official_ once it has been made into a release on
|
|
|
|
[GitHub](https://github.com/enso-org/enso/releases). Once official, a release
|
|
|
|
may not be changed in any way, except to mark it as broken.
|
|
|
|
|
2020-07-08 16:54:41 +03:00
|
|
|
#### Release Assets Structure
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-08 16:54:41 +03:00
|
|
|
Each release contains a build of the Enso engine and native launcher binaries
|
|
|
|
for each supported platform. Moreover, for convenience, it should include
|
|
|
|
bundles containing native launcher binaries and the latest engine build for each
|
|
|
|
platform. So each release should contain the following assets:
|
|
|
|
|
2020-08-07 12:18:09 +03:00
|
|
|
- `enso-bundle-<version>-linux-amd64.tar.gz`
|
|
|
|
- `enso-bundle-<version>-macos-amd64.tar.gz`
|
2020-07-08 16:54:41 +03:00
|
|
|
- `enso-bundle-<version>-windows-amd64.zip`
|
2020-08-07 12:18:09 +03:00
|
|
|
- `enso-engine-<version>-linux-amd64.tar.gz`
|
|
|
|
- `enso-engine-<version>-macos-amd64.tar.gz`
|
|
|
|
- `enso-engine-<version>-windows-amd64.zip`
|
|
|
|
- `enso-launcher-<version>-linux-amd64.tar.gz`
|
|
|
|
- `enso-launcher-<version>-macos-amd64.tar.gz`
|
2020-07-08 16:54:41 +03:00
|
|
|
- `enso-launcher-<version>-windows-amd64.zip`
|
2020-07-21 11:14:26 +03:00
|
|
|
- `manifest.yaml`
|
2020-07-08 16:54:41 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
#### Marking a Release as Broken
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
We intend to _never_ delete a release from GitHub, as users may have projects
|
|
|
|
that depend on specific versions of Enso. Instead, we provide a mechanism for
|
|
|
|
marking releases as broken that works as follows:
|
|
|
|
|
|
|
|
- An empty file named `broken` is uploaded to the release.
|
|
|
|
- The release description is edited to visibly mark the release as broken.
|
|
|
|
|
2020-07-21 15:59:40 +03:00
|
|
|
A broken release is one that _must not_ be downloaded by the launcher unless a
|
|
|
|
project specifies _an exact version match_, and it _must not_ be used in new
|
2020-07-01 17:26:49 +03:00
|
|
|
projects by the launcher unless _explicitly_ specified by the user as an exact
|
|
|
|
version match.
|
|
|
|
|
2020-09-14 12:05:37 +03:00
|
|
|
When the release is marked as broken at GitHub, a GitHub Actions
|
|
|
|
[Workflow](fallback-launcher-release-infrastructure.md#marking-the-release-as-broken)
|
|
|
|
is triggered that also updates the release in the fallback mechanism. Given its
|
|
|
|
current implementation is prone to race conditions when updating releases, the
|
|
|
|
`broken` file should be added to releases one by one, making sure that only one
|
|
|
|
update workflow is running at the same time and that no release workflows are
|
|
|
|
running in parallel with it.
|
|
|
|
|
|
|
|
In an unusual situation in which you want to upload a release that is marked as
|
|
|
|
broken from the start, you should first publish it in a non-broken state and
|
|
|
|
only mark it as broken after publishing. That is because the GitHub Workflow
|
|
|
|
that will persist the broken mark to S3 is not triggered for release drafts.
|
|
|
|
|
|
|
|
> **When marking the release as broken, you should make sure that the workflow
|
|
|
|
> persisting the broken mark to Se has succeeded and re-run it if necessary.**
|
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
### Release Notes
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
Release notes should contain a summary of the changes made between the last
|
2021-01-05 17:14:08 +03:00
|
|
|
release and the current release. They should follow the template given below,
|
|
|
|
and are contained in the `RELEASES.md` file in the repository root.
|
2020-07-01 17:26:49 +03:00
|
|
|
|
|
|
|
```md
|
|
|
|
# Enso x.y.z (YYYY-MM-DD)
|
|
|
|
|
|
|
|
## Language
|
|
|
|
|
|
|
|
- A list of language-level changes.
|
|
|
|
|
2021-01-05 17:14:08 +03:00
|
|
|
## Interpreter/Runtime
|
2020-07-01 17:26:49 +03:00
|
|
|
|
|
|
|
- A list of changes to the Enso interpreter.
|
|
|
|
|
2021-01-05 17:14:08 +03:00
|
|
|
## Type System
|
2020-07-01 17:26:49 +03:00
|
|
|
|
2021-01-05 17:14:08 +03:00
|
|
|
- A list of type-system changes.
|
2020-07-01 17:26:49 +03:00
|
|
|
|
|
|
|
## Tooling
|
|
|
|
|
|
|
|
- A list of changes to the Enso language tooling.
|
|
|
|
|
|
|
|
## Libraries
|
|
|
|
|
|
|
|
- A list of changes to the Enso core libraries.
|
|
|
|
|
|
|
|
## Stabilised Features
|
|
|
|
|
|
|
|
- A list of stabilised APIs and/or features.
|
|
|
|
|
|
|
|
## Misc
|
|
|
|
|
|
|
|
- A list of miscellaneous changes.
|
|
|
|
|
|
|
|
## Internal Only
|
|
|
|
|
|
|
|
- A list of changes that do not have user-facing impact, but represent
|
|
|
|
significant improvements to the internals of Enso and related tools.
|
|
|
|
```
|
|
|
|
|
2021-01-06 11:57:02 +03:00
|
|
|
If there are no changes for a section, the section may be removed.
|
2020-07-01 17:26:49 +03:00
|
|
|
|
2021-01-05 17:14:08 +03:00
|
|
|
The releases file is an ongoing record of changes, and may diverge between
|
2020-07-01 17:26:49 +03:00
|
|
|
`main` and the various release branches.
|
|
|
|
|
|
|
|
## Version Support
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
We aim to support a given major version for some period of time after the
|
|
|
|
release of the next major version. For a detailed breakdown of the major
|
|
|
|
versions that are currently supported, please see the [security](./security.md)
|
|
|
|
document.
|
|
|
|
|
|
|
|
## Working on the Current Release
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
When working on the current release, development should take place against the
|
|
|
|
`main` branch. When it is time to cut a release, the new commits on the main
|
|
|
|
branch are cherry-picked onto the current release branch. From there, the
|
|
|
|
release proceeds as described in [release workflow](#release-workflow) above.
|
|
|
|
|
|
|
|
## Backporting Fixes
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 17:26:49 +03:00
|
|
|
Supporting a major version for some time after the release of the next major
|
|
|
|
version will sometimes require backporting a fix to the previous major version
|
|
|
|
from the current version or from `main`.
|
|
|
|
|
|
|
|
Backporting should only be used for applying _fixes_, not the addition of new
|
|
|
|
features.
|
|
|
|
|
|
|
|
The process for performing such a backport is as follows:
|
|
|
|
|
|
|
|
1. Create a new branch called `backport/version/fix-name`, where `version`
|
|
|
|
matches the version string of the corresponding release branch. This branch
|
|
|
|
should branch off the corresponding release branch.
|
|
|
|
2. Back-port the fix to the newly created `backport` branch. This can be done
|
|
|
|
by:
|
|
|
|
- Cherry-picking the commit and performing fixups (preferred).
|
|
|
|
- Re-implementing the fix manually (if cherry-picking will not work due to
|
|
|
|
progression of the codebase).
|
|
|
|
3. Submit your `backport/version/fix-name` branch for review as a pull-request
|
|
|
|
into the `release/version` branch.
|
|
|
|
4. Once the PR has passed CI and been approved by the appropriate reviewers, it
|
|
|
|
can be merged into the release branch.
|