From 1d4ab1ea653e89af59ddd3fc7ce5f57778e1f695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Mon, 2 Oct 2023 15:17:23 +0200 Subject: [PATCH 1/8] Add RELEASES.md --- project/RELEASES.md | 185 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 project/RELEASES.md diff --git a/project/RELEASES.md b/project/RELEASES.md new file mode 100644 index 000000000000..2eb4f56c9104 --- /dev/null +++ b/project/RELEASES.md @@ -0,0 +1,185 @@ +# Scala LTS maintenance and release cycle + +## Scala LTS and Scala Next + +Since Scala 3.3.0, there are always two versions of Scala 3 being developed at the same time: Scala Next and Scala LTS. + +Scala Next continues all practices since before the 3.3.0. It maintains backward output (TASTy and binary) compatibility between all versions and forward output compatibility between patch releases of the same minor version. This version is being actively developed on the `main` branch. All new bug fixes and features will be merged to that version, i.e., to the `main` branch. + +Scala LTS is a selected minor version (currently 3.3) that, unlike all other minor versions, has patch releases even though there is a newer minor version. Aside from our standard output compatibility guarantees, it is intended to preserve backward source compatibility. As no new features and bugfixes (with the rare exception of LTS-only hotfixes) will be developed for LTS, but instead, selected changes from the Next branch will be backported, there is no development branch for Scala LTS. All changes are merged to release branches instead. The commit marked with a full release tag for any version is the base for the release branch for the next version. + +## What should be backported? + +The decision of what changes merged to the `main` branch should be backported is taken according to the following flowchart: + +```mermaid +flowchart TB + start(["PR relevant for LTS was merged to main branch"]) + --> + cve{"Is this + a fix for a CVE?"} + -- yes --> ocb + + subgraph "CVE" + ocb{"Does it cause + any new failures + in the full CB?"} + + -- yes --> + regFix[\"Try to provide + a followup fix for + a regressions"/] + + -- failure --> + debate[\"Possible workarounds + for new regressions are discussed + by the compiler team"/] + + regFix -- success --> ocb + end + ocb -- no --> acc + debate -->|"decision on + the recommended + workarounds"| acc + + cve -- no --> + incompat{"Does the fix + break forward + compatibiliy?"} + -- yes --> reject + + incompat -- no --> + + regression{"Is this a fix for + a regression present + also in LTS?"} + -- yes --> + + regIsLTS{"Was the last version + not affected by + the regression released + before 3.3.0?"} + -- no --> ocbReg + + subgraph "LTS Regression" + ocbReg{"Does it cause + any new failures + in the full CB?"} + + -- yes --> + regFixReg[\"Try to provide + a followup fix for + a regressions"/] + + -- failure --> + debateReg[\"Impact of both new and old regression + and possible workarounds + are discussed by the compiler team."/] + + regFixReg -- success --> ocbReg + end + ocbReg -- no --> acc + debateReg -->|"decision on + the recommended + workarounds for + the new regression"| acc + debateReg -->|"decision on + the recommended + workarounds for + the old regression"| reject + + regression -- no --> types + regIsLTS -- yes --> types + types{"Can the fix + change types + in any correct + Scala 3 code?"} + -- yes --> request + types -- no --> ocbOther + + request{"Is backport + of the fix + heavily requested?"} + -- yes --> debateReq + request -- no --> reject + + debateReq[\"Possibility of + the backport is discussed + by the compiler team"/] + --> |"backport is rejected"| reject + debateReq --> |"backport is accepted"| ocbOther + + subgraph "Other Fixes" + ocbOther{"Does it cause + any new failures + in the full CB?"} + + -- yes --> + regFixOther[\"Try to provide + a followup fix for + a regressions"/] + -- success --> ocbOther + + ocbOther -- no --> + lint{"Does it introduce + any new warnings + behind flags?"} + -- yes --> + lintOcb{"Does it cause any + new failures in the full CB + after forcing a new flag?"} + -- yes --> regFixOther + end + + lint -- no --> acc + lintOcb -- no --> acc + regFixOther -- failure --> reject + + acc(["The PR is backported"]) + reject(["The PR is not backported"]) + + + + + + +``` + +## How should things be backported? + +The backporting process is tracked by a GitHub Project in the lampepfl organization. Every PR merged to the `main` branch is automatically added to the `Needs Assessment` column. Those PRs are reviewed by the release officer or other appointed person. They can decide to remove them from the project (backport rejected) or to move them to the `Backporting in progress` column. If the PR with the backport has any differences from the original PR, the person doing the backport will ask the author and reviewers of the original change to review the backport. After merging the backport, the PR will be moved to the `Backport done` column and, after the release, to the `Released` column. + +Maintainers can request backporting the entirety or a part of previously rejected PR by adding it to the `Backport requested` column. + +## The release cycle + +Releasing two different lines of the language at the same time requires some changes to the release procedures. We no longer release RC versions for patch releases of Scala Next. RC versions of patch releases of Scala LTS are released two weeks before the intended full release date. RC versions of Scala Next minor releases are released four weeks before the intended full release date. + +The releases will be performed according to the 6-week cycles. Actions of each week are started to be performed on Tuesday. This is because the compiler team meetings take place on Mondays, and some concerns might be raised during them. + +If we assume that the cycle starts on Tuesday `t` and `t + 1` is the next Tuesday, the timeline looks as follows: + +- `t` - release of Scala Next and RC1 for the next Scala LTS patch. +- `t + 2` - release of the next Scala LTS patch. If the next Scala Next version is a minor version, RC1 of that version is released. +- `t + 6` - the start of the new release cycle + +### Dealing with delays + +It is possible that there will be problems in the RC releases that require fixes and further release candidates. We will not publish a full release in the same week as an RC. This means that delay can occur. + +In the case of LTS releases, there are four weeks to fix the problem if the versions is to be released before the RC1 of the next patch. If we don't solve the issue two weeks before the start of the next release cycle, we will find a commit on the release branch of the current version that the problem was not yet present and release it as an RC. Before releasing the RC1 for the next version, we will either find a fix for the problem or rebase the next release branch so that the offending change is removed from the branch. + +In the case of minor Scala Next releases, if we cannot have a satisfying RC on time, we can skip releasing the stable Scala Next version in the given release cycle. This means there may be cycles during which we release only Scala LTS. + +Accounting for delays adds these points to the timeline above: + +- `t + 4` - last possible moment to release RC for the Scala LTS patch, which is trying to fix a problem +- `t + 5` - If no RC exists for Scala LTS fixing a problem, a version based on the last non-problematic commit is released. Also, this is the last moment to release RC for the Scala Next minor. Otherwise, we will skip the Scala Next release in the next cycle. + +### What is being released? + +For the Scala LTS, what is released as an RC is always the current head of the release branch for the next release. + +For the Scala Next minor releases RC, it is the head of the `main` branch. + +For the Scala Next patches, there are no RCs. As a point of cut-off of the release, we are choosing one relatively recent commit from the `main` branch on which a full Open Community Build was run before the decision. The default choice here is the commit on which the last weekly community build was run. From efcdefa3b56cc5b367592795f5cb7e2ddd242874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Mon, 2 Oct 2023 15:31:18 +0200 Subject: [PATCH 2/8] Add clarification about backport labels remove blank lines --- project/RELEASES.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/project/RELEASES.md b/project/RELEASES.md index 2eb4f56c9104..92a62ce88312 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -137,12 +137,6 @@ flowchart TB acc(["The PR is backported"]) reject(["The PR is not backported"]) - - - - - - ``` ## How should things be backported? @@ -151,6 +145,8 @@ The backporting process is tracked by a GitHub Project in the lampepfl organizat Maintainers can request backporting the entirety or a part of previously rejected PR by adding it to the `Backport requested` column. +Labels form the `backport:*` family retains their current meaning, i.e., they are used to mark things on the `main` branch that should be backported to the RC. Due to dropping the RCs for the Scala Next patch releases (more about it below), they will be only relevant for the Scala Next minor versions. + ## The release cycle Releasing two different lines of the language at the same time requires some changes to the release procedures. We no longer release RC versions for patch releases of Scala Next. RC versions of patch releases of Scala LTS are released two weeks before the intended full release date. RC versions of Scala Next minor releases are released four weeks before the intended full release date. From 09eea2359f3f0658e5d2b13c2aefc6545c95e11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 10 Oct 2023 15:10:39 +0200 Subject: [PATCH 3/8] Split the release cycles Bring back RCs for all versions --- project/RELEASES.md | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/project/RELEASES.md b/project/RELEASES.md index 92a62ce88312..b226f6a3b2b1 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -147,35 +147,22 @@ Maintainers can request backporting the entirety or a part of previously rejecte Labels form the `backport:*` family retains their current meaning, i.e., they are used to mark things on the `main` branch that should be backported to the RC. Due to dropping the RCs for the Scala Next patch releases (more about it below), they will be only relevant for the Scala Next minor versions. -## The release cycle +## The release cycles -Releasing two different lines of the language at the same time requires some changes to the release procedures. We no longer release RC versions for patch releases of Scala Next. RC versions of patch releases of Scala LTS are released two weeks before the intended full release date. RC versions of Scala Next minor releases are released four weeks before the intended full release date. +Two separate lines of the compiler require two intertwined release cycles. -The releases will be performed according to the 6-week cycles. Actions of each week are started to be performed on Tuesday. This is because the compiler team meetings take place on Mondays, and some concerns might be raised during them. +Scala Next strictly follows a six-week release train model. Every six weeks, a release candidate for the next version is published. During the next six weeks, we may release subsequent RCs containing fixes to critical bugs found in the previous RCs. A bug may be considered critical only if it is a regression; that is, some code that was correctly passing a compilation in any earlier versions of Scala 3 is now either failing compilation, crashing the compiler, or generating incorrect output (bytecode or TASTy). The compiler team decides which regression is considered a critical bug that requires a new RC and which can be fixed in the next release. After six weeks, the clock resets, the last released RC is promoted to a stable release, and the RC for the next version is published. -If we assume that the cycle starts on Tuesday `t` and `t + 1` is the next Tuesday, the timeline looks as follows: +If there is less than a week left before the release, and the last RC still contains critical bugs, the compiler team may decide to postpone publishing the stable version. There will always be at least one whole week between publishing the last RC and promoting it to the status of a stable release. This delay doesn't affect the RC-1 date for the next version. It will be released six weeks after the previous version's RC-1. The goal is to ensure that delay in releasing one version doesn't cause future releases to be larger in terms of the number of merged PRs, as it can make regressions inside of them more complex to pinpoint and fix, leading to the accumulation of delays for future versions. -- `t` - release of Scala Next and RC1 for the next Scala LTS patch. -- `t + 2` - release of the next Scala LTS patch. If the next Scala Next version is a minor version, RC1 of that version is released. -- `t + 6` - the start of the new release cycle +Scala LTS has a more relaxed release model. RC-1 for the next version is published after the stable release of the previous version. Similar to Scala Next, we may release more RCs, fixing bugs. Unlike Scala Next, the bug doesn't need to be considered critical to guarantee the new RC. For Sala LTS, our primary goal is stability, so delays are acceptable. We guarantee that a stable release is at least six weeks after the first RC and at least one week after the last RC. -### Dealing with delays +The two release cycles are not synchronized in any way, as any synchronization would be broken on any delay in the Scala LTS cycle. -It is possible that there will be problems in the RC releases that require fixes and further release candidates. We will not publish a full release in the same week as an RC. This means that delay can occur. - -In the case of LTS releases, there are four weeks to fix the problem if the versions is to be released before the RC1 of the next patch. If we don't solve the issue two weeks before the start of the next release cycle, we will find a commit on the release branch of the current version that the problem was not yet present and release it as an RC. Before releasing the RC1 for the next version, we will either find a fix for the problem or rebase the next release branch so that the offending change is removed from the branch. - -In the case of minor Scala Next releases, if we cannot have a satisfying RC on time, we can skip releasing the stable Scala Next version in the given release cycle. This means there may be cycles during which we release only Scala LTS. - -Accounting for delays adds these points to the timeline above: - -- `t + 4` - last possible moment to release RC for the Scala LTS patch, which is trying to fix a problem -- `t + 5` - If no RC exists for Scala LTS fixing a problem, a version based on the last non-problematic commit is released. Also, this is the last moment to release RC for the Scala Next minor. Otherwise, we will skip the Scala Next release in the next cycle. +The compiler team may pause the release cycles for a week or two on occasions such as New Year or a conference that most of the team is attending. ### What is being released? For the Scala LTS, what is released as an RC is always the current head of the release branch for the next release. -For the Scala Next minor releases RC, it is the head of the `main` branch. - -For the Scala Next patches, there are no RCs. As a point of cut-off of the release, we are choosing one relatively recent commit from the `main` branch on which a full Open Community Build was run before the decision. The default choice here is the commit on which the last weekly community build was run. +For the Scala Next minor releases RC, by default, it is the head of the `main` branch. Based on the Open Community Build results, the compiler team may decide to base the release on some earlier state of the branch. From 6d0072b779f8bdabb9e8d2ba97a61e61c84607dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 10 Oct 2023 15:15:38 +0200 Subject: [PATCH 4/8] Explain usage of backport lables --- project/RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/RELEASES.md b/project/RELEASES.md index b226f6a3b2b1..66ab03518488 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -145,7 +145,7 @@ The backporting process is tracked by a GitHub Project in the lampepfl organizat Maintainers can request backporting the entirety or a part of previously rejected PR by adding it to the `Backport requested` column. -Labels form the `backport:*` family retains their current meaning, i.e., they are used to mark things on the `main` branch that should be backported to the RC. Due to dropping the RCs for the Scala Next patch releases (more about it below), they will be only relevant for the Scala Next minor versions. +Labels from the `backport:*` are used only for backports that targets versions with already released RCs. They can be used to mark changes on the main that are fixing a critical bug present in the Scala Next RC release or changes that were backported to the future Scala LTS versions that should be also backported to the current RCs. ## The release cycles From f41f46aaa5c60c81a8bf63436e0ed758938385be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 10 Oct 2023 15:17:16 +0200 Subject: [PATCH 5/8] Add link to backport project --- project/RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/RELEASES.md b/project/RELEASES.md index 66ab03518488..6c25f9ca5b62 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -141,7 +141,7 @@ flowchart TB ## How should things be backported? -The backporting process is tracked by a GitHub Project in the lampepfl organization. Every PR merged to the `main` branch is automatically added to the `Needs Assessment` column. Those PRs are reviewed by the release officer or other appointed person. They can decide to remove them from the project (backport rejected) or to move them to the `Backporting in progress` column. If the PR with the backport has any differences from the original PR, the person doing the backport will ask the author and reviewers of the original change to review the backport. After merging the backport, the PR will be moved to the `Backport done` column and, after the release, to the `Released` column. +The backporting process is tracked by [a GitHub Project](https://github.com/orgs/lampepfl/projects/6) in the lampepfl organization. Every PR merged to the `main` branch is automatically added to the `Needs Assessment` column. Those PRs are reviewed by the release officer or other appointed person. They can decide to remove them from the project (backport rejected) or to move them to the `Backporting in progress` column. If the PR with the backport has any differences from the original PR, the person doing the backport will ask the author and reviewers of the original change to review the backport. After merging the backport, the PR will be moved to the `Backport done` column and, after the release, to the `Released` column. Maintainers can request backporting the entirety or a part of previously rejected PR by adding it to the `Backport requested` column. From 4f80ed738cc25135f417ed943fd6a526d9d3aa32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 10 Oct 2023 15:18:29 +0200 Subject: [PATCH 6/8] Swap regIsLTS logic --- project/RELEASES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project/RELEASES.md b/project/RELEASES.md index 6c25f9ca5b62..87125a6ccdc7 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -56,10 +56,10 @@ flowchart TB -- yes --> regIsLTS{"Was the last version - not affected by + affected by the regression released before 3.3.0?"} - -- no --> ocbReg + -- yes --> ocbReg subgraph "LTS Regression" ocbReg{"Does it cause @@ -89,7 +89,7 @@ flowchart TB the old regression"| reject regression -- no --> types - regIsLTS -- yes --> types + regIsLTS -- no --> types types{"Can the fix change types in any correct From 8a4d1174f6f4010e49d507eaafaca81795cbd3c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Thu, 19 Oct 2023 13:35:26 +0200 Subject: [PATCH 7/8] Add explanations for used abbreviations --- project/RELEASES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/project/RELEASES.md b/project/RELEASES.md index 87125a6ccdc7..f4f2a529f17a 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -139,6 +139,10 @@ flowchart TB reject(["The PR is not backported"]) ``` +CVE stands for Common Vulnerabilities and Exposures and in the chart above it means an issue with an CVE-ID assigned to it. + +CB stands for Community Build, and by full CB we mean the full run of [the Scala 3 Open Community Build](https://github.com/VirtusLab/community-build3). + ## How should things be backported? The backporting process is tracked by [a GitHub Project](https://github.com/orgs/lampepfl/projects/6) in the lampepfl organization. Every PR merged to the `main` branch is automatically added to the `Needs Assessment` column. Those PRs are reviewed by the release officer or other appointed person. They can decide to remove them from the project (backport rejected) or to move them to the `Backporting in progress` column. If the PR with the backport has any differences from the original PR, the person doing the backport will ask the author and reviewers of the original change to review the backport. After merging the backport, the PR will be moved to the `Backport done` column and, after the release, to the `Released` column. From a1899995ab68505de56a51eca69e020994c96215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Thu, 19 Oct 2023 13:37:57 +0200 Subject: [PATCH 8/8] RC-1 -> RC1 --- project/RELEASES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/RELEASES.md b/project/RELEASES.md index f4f2a529f17a..1dcb6cba7cc7 100644 --- a/project/RELEASES.md +++ b/project/RELEASES.md @@ -157,9 +157,9 @@ Two separate lines of the compiler require two intertwined release cycles. Scala Next strictly follows a six-week release train model. Every six weeks, a release candidate for the next version is published. During the next six weeks, we may release subsequent RCs containing fixes to critical bugs found in the previous RCs. A bug may be considered critical only if it is a regression; that is, some code that was correctly passing a compilation in any earlier versions of Scala 3 is now either failing compilation, crashing the compiler, or generating incorrect output (bytecode or TASTy). The compiler team decides which regression is considered a critical bug that requires a new RC and which can be fixed in the next release. After six weeks, the clock resets, the last released RC is promoted to a stable release, and the RC for the next version is published. -If there is less than a week left before the release, and the last RC still contains critical bugs, the compiler team may decide to postpone publishing the stable version. There will always be at least one whole week between publishing the last RC and promoting it to the status of a stable release. This delay doesn't affect the RC-1 date for the next version. It will be released six weeks after the previous version's RC-1. The goal is to ensure that delay in releasing one version doesn't cause future releases to be larger in terms of the number of merged PRs, as it can make regressions inside of them more complex to pinpoint and fix, leading to the accumulation of delays for future versions. +If there is less than a week left before the release, and the last RC still contains critical bugs, the compiler team may decide to postpone publishing the stable version. There will always be at least one whole week between publishing the last RC and promoting it to the status of a stable release. This delay doesn't affect the RC1 date for the next version. It will be released six weeks after the previous version's RC1. The goal is to ensure that delay in releasing one version doesn't cause future releases to be larger in terms of the number of merged PRs, as it can make regressions inside of them more complex to pinpoint and fix, leading to the accumulation of delays for future versions. -Scala LTS has a more relaxed release model. RC-1 for the next version is published after the stable release of the previous version. Similar to Scala Next, we may release more RCs, fixing bugs. Unlike Scala Next, the bug doesn't need to be considered critical to guarantee the new RC. For Sala LTS, our primary goal is stability, so delays are acceptable. We guarantee that a stable release is at least six weeks after the first RC and at least one week after the last RC. +Scala LTS has a more relaxed release model. RC1 for the next version is published after the stable release of the previous version. Similar to Scala Next, we may release more RCs, fixing bugs. Unlike Scala Next, the bug doesn't need to be considered critical to guarantee the new RC. For Sala LTS, our primary goal is stability, so delays are acceptable. We guarantee that a stable release is at least six weeks after the first RC and at least one week after the last RC. The two release cycles are not synchronized in any way, as any synchronization would be broken on any delay in the Scala LTS cycle.