From e8362c0c1641d86936b80ab956e1768ef7bdd6f5 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Tue, 10 Dec 2024 23:39:40 +0100 Subject: [PATCH 1/5] Update reference version to 3.6.3-RC1 --- project/Build.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index f36171aabbcd..49e2215eb187 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -97,7 +97,7 @@ object Build { * - In release branch it should be the last stable release * 3.6.0-RC1 was released as 3.6.0 - it's having and experimental TASTy version */ - val referenceVersion = "3.6.0" + val referenceVersion = "3.6.3-RC1" /** Version of the Scala compiler targeted in the current release cycle * Contains a version without RC/SNAPSHOT/NIGHTLY specific suffixes From aa7bf6bbdd990eba524b73ec1a7ff4675dac7b4e Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Tue, 10 Dec 2024 23:43:02 +0100 Subject: [PATCH 2/5] Update mima previous dotty version --- project/Build.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 49e2215eb187..2280dd13253d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -149,9 +149,9 @@ object Build { * For a developedVersion `3.M.P` the mimaPreviousDottyVersion should be set to: * - `3.M.0` if `P > 0` * - `3.(M-1).0` if `P = 0` - * 3.6.1 is an exception from this rule - 3.6.0 was a broken release + * 3.6.2 is an exception from this rule - 3.6.0 was a broken release, 3.6.1 was hotfix (unstable) release */ - val mimaPreviousDottyVersion = "3.6.1" + val mimaPreviousDottyVersion = "3.6.2" /** LTS version against which we check binary compatibility. * From 5ae8f0f61fc6a62873d65e7b0a8f717d4988392d Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Tue, 10 Dec 2024 23:48:19 +0100 Subject: [PATCH 3/5] Bump TASTy version, add documentation and runtime test to ensure correctness of set TASTY version --- project/Build.scala | 29 ++++++++- tasty/src/dotty/tools/tasty/TastyFormat.scala | 2 +- .../tools/tasty/BuildTastyVersionTest.scala | 65 +++++++++++++++++++ 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala diff --git a/project/Build.scala b/project/Build.scala index 2280dd13253d..8bf53f8cb5b6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -93,9 +93,10 @@ object Build { /** Version of the Scala compiler used to build the artifacts. * Reference version should track the latest version pushed to Maven: - * - In main branch it should be the last RC version (using experimental TASTy required for non-bootstrapped tests) + * - In main branch it should be the last RC version * - In release branch it should be the last stable release - * 3.6.0-RC1 was released as 3.6.0 - it's having and experimental TASTy version + * + * Warning: Change of this variable needs to consulted with `expectedTastyVersion` */ val referenceVersion = "3.6.3-RC1" @@ -105,6 +106,8 @@ object Build { * * Should only be referred from `dottyVersion` or settings/tasks requiring simplified version string, * eg. `compatMode` or Windows native distribution version. + * + * Warning: Change of this variable might require updating `expectedTastyVersion` */ val developedVersion = "3.6.4" @@ -116,6 +119,24 @@ object Build { * During final, stable release is set exactly to `developedVersion`. */ val baseVersion = s"$developedVersion-RC1" + + /** The version of TASTY that should be emitted, checked in runtime test + * For defails on how TASTY version should be set see related discussions: + * - https://github.com/scala/scala3/issues/13447#issuecomment-912447107 + * - https://github.com/scala/scala3/issues/14306#issuecomment-1069333516 + * - https://github.com/scala/scala3/pull/19321 + * + * Simplified rules, given 3.$minor.$patch = $developedVersion + * - Major version is always 28 + * - TASTY minor version: + * - in main (NIGHTLY): {if $patch == 0 then $minor else ${minor + 1}} + * - in release branch is always equal to $minor + * - TASTY experimental version: + * - in main (NIGHTLY) is always experimental + * - in release candidate branch is experimental if {patch == 0} + * - in stable release is always non-experimetnal + */ + val expectedTastyVersion = "28.7-experimental-1" /** Final version of Scala compiler, controlled by environment variables. */ val dottyVersion = { @@ -2424,6 +2445,10 @@ object Build { settings(disableDocSetting). settings( versionScheme := Some("semver-spec"), + Test / envVars ++= Map( + "EXPECTED_TASTY_VERSION" -> expectedTastyVersion, + "BASE_VERSION" -> baseVersion + ), if (mode == Bootstrapped) Def.settings( commonMiMaSettings, mimaForwardIssueFilters := MiMaFilters.TastyCore.ForwardsBreakingChanges, diff --git a/tasty/src/dotty/tools/tasty/TastyFormat.scala b/tasty/src/dotty/tools/tasty/TastyFormat.scala index 8f5f9d57a8a5..8ff590fefec5 100644 --- a/tasty/src/dotty/tools/tasty/TastyFormat.scala +++ b/tasty/src/dotty/tools/tasty/TastyFormat.scala @@ -324,7 +324,7 @@ object TastyFormat { * compatibility, but remains backwards compatible, with all * preceding `MinorVersion`. */ - final val MinorVersion: Int = 6 + final val MinorVersion: Int = 7 /** Natural Number. The `ExperimentalVersion` allows for * experimentation with changes to TASTy without committing diff --git a/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala b/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala new file mode 100644 index 000000000000..b6a54ef45d68 --- /dev/null +++ b/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala @@ -0,0 +1,65 @@ +package dotty.tools.tasty + +import org.junit.Assert._ +import org.junit.Test + +import TastyBuffer._ + +// Tests ensuring TASTY version emitted by compiler is matching expected TASTY version +class BuildTastyVersionTest { + + val CurrentTastyVersion = TastyVersion(TastyFormat.MajorVersion, TastyFormat.MinorVersion, TastyFormat.ExperimentalVersion) + + // Needs to be defined in build Test/envVars + val ExpectedTastyVersionEnvVar = "EXPECTED_TASTY_VERSION" + val BaseVersionEnvVar = "BASE_VERSION" + + @Test def testBuildTastyVersion(): Unit = { + val expectedVersion = sys.env.get(ExpectedTastyVersionEnvVar) + .getOrElse(fail(s"Env variable $ExpectedTastyVersionEnvVar not defined")) + .match { + case s"$major.$minor-experimental-$experimental" => TastyVersion(major.toInt, minor.toInt, experimental.toInt) + case s"$major.$minor" if minor.forall(_.isDigit) => TastyVersion(major.toInt, minor.toInt, 0) + case other => fail(s"Invalid TASTY version string: $other") + } + assertEquals(CurrentTastyVersion, expectedVersion) + } + + // Tested only in nightly / release builds + // Protects from publishing artifacts with incorrect TASTY version + @Test def testReleasedTastyVersion(): Unit = { + lazy val (minor, patch, isRC) = sys.env.get(BaseVersionEnvVar) + .getOrElse(fail(s"Env variable $BaseVersionEnvVar not defined")) + .match { + case s"3.$minor.$patch-${_}" => (minor.toInt, patch.toInt, true) + case s"3.$minor.$patch" => (minor.toInt, patch.toInt, false) + case other => fail(s"Invalid Scala base version string: $other") + } + + if sys.env.get("NIGHTLYBUILD").contains("yes") then { + assertTrue( + "TASTY needs to be experimental in nightly builds", + CurrentTastyVersion.isExperimental + ) + assertEquals( + CurrentTastyVersion.minor, + if patch == 0 then minor else (minor + 1) + ) + } else if sys.env.get("RELEASEBUILD").contains("yes") then { + assertEquals( + "Minor versions of TASTY vesion and Scala version should match in stable release", + CurrentTastyVersion.minor, minor + ) + if isRC then + assertEquals( + "TASTy should be experimental when releasing a new minor version RC", + CurrentTastyVersion.isExperimental, patch == 0 + ) + else + assertFalse( + "Stable version cannot use experimental TASTY", + CurrentTastyVersion.isExperimental + ) + } + } +} From f326b30511d9a043e1905b576ff46898b39ac4fc Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Wed, 11 Dec 2024 12:41:44 +0100 Subject: [PATCH 4/5] Remove never executed test case --- project/Build.scala | 1 - .../tools/tasty/BuildTastyVersionTest.scala | 39 ------------------- 2 files changed, 40 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 8bf53f8cb5b6..e461240fde11 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -2447,7 +2447,6 @@ object Build { versionScheme := Some("semver-spec"), Test / envVars ++= Map( "EXPECTED_TASTY_VERSION" -> expectedTastyVersion, - "BASE_VERSION" -> baseVersion ), if (mode == Bootstrapped) Def.settings( commonMiMaSettings, diff --git a/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala b/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala index b6a54ef45d68..d2e62e1f9eb0 100644 --- a/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala +++ b/tasty/test/dotty/tools/tasty/BuildTastyVersionTest.scala @@ -12,7 +12,6 @@ class BuildTastyVersionTest { // Needs to be defined in build Test/envVars val ExpectedTastyVersionEnvVar = "EXPECTED_TASTY_VERSION" - val BaseVersionEnvVar = "BASE_VERSION" @Test def testBuildTastyVersion(): Unit = { val expectedVersion = sys.env.get(ExpectedTastyVersionEnvVar) @@ -24,42 +23,4 @@ class BuildTastyVersionTest { } assertEquals(CurrentTastyVersion, expectedVersion) } - - // Tested only in nightly / release builds - // Protects from publishing artifacts with incorrect TASTY version - @Test def testReleasedTastyVersion(): Unit = { - lazy val (minor, patch, isRC) = sys.env.get(BaseVersionEnvVar) - .getOrElse(fail(s"Env variable $BaseVersionEnvVar not defined")) - .match { - case s"3.$minor.$patch-${_}" => (minor.toInt, patch.toInt, true) - case s"3.$minor.$patch" => (minor.toInt, patch.toInt, false) - case other => fail(s"Invalid Scala base version string: $other") - } - - if sys.env.get("NIGHTLYBUILD").contains("yes") then { - assertTrue( - "TASTY needs to be experimental in nightly builds", - CurrentTastyVersion.isExperimental - ) - assertEquals( - CurrentTastyVersion.minor, - if patch == 0 then minor else (minor + 1) - ) - } else if sys.env.get("RELEASEBUILD").contains("yes") then { - assertEquals( - "Minor versions of TASTY vesion and Scala version should match in stable release", - CurrentTastyVersion.minor, minor - ) - if isRC then - assertEquals( - "TASTy should be experimental when releasing a new minor version RC", - CurrentTastyVersion.isExperimental, patch == 0 - ) - else - assertFalse( - "Stable version cannot use experimental TASTY", - CurrentTastyVersion.isExperimental - ) - } - } } From 6bb9559dab49f061c36676317c63fabf5ab8e333 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Wed, 11 Dec 2024 15:17:14 +0100 Subject: [PATCH 5/5] Fix typo and move TASTy version check to build.sbt so it can be tested before releasing artifacts --- project/Build.scala | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index e461240fde11..db3f149cbab6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -96,7 +96,7 @@ object Build { * - In main branch it should be the last RC version * - In release branch it should be the last stable release * - * Warning: Change of this variable needs to consulted with `expectedTastyVersion` + * Warning: Change of this variable needs to be consulted with `expectedTastyVersion` */ val referenceVersion = "3.6.3-RC1" @@ -137,6 +137,7 @@ object Build { * - in stable release is always non-experimetnal */ val expectedTastyVersion = "28.7-experimental-1" + checkReleasedTastyVersion() /** Final version of Scala compiler, controlled by environment variables. */ val dottyVersion = { @@ -2497,6 +2498,34 @@ object Build { case Bootstrapped => commonBootstrappedSettings }) } + + /* Tests TASTy version invariants during NIGHLY, RC or Stable releases */ + def checkReleasedTastyVersion(): Unit = { + lazy val (scalaMinor, scalaPatch, scalaIsRC) = baseVersion.split("\\.|-").take(4) match { + case Array("3", minor, patch) => (minor.toInt, patch.toInt, false) + case Array("3", minor, patch, _) => (minor.toInt, patch.toInt, true) + case other => sys.error(s"Invalid Scala base version string: $baseVersion") + } + lazy val (tastyMinor, tastyIsExperimental) = expectedTastyVersion.split("\\.|-").take(4) match { + case Array("28", minor) => (minor.toInt, false) + case Array("28", minor, "experimental", _) => (minor.toInt, true) + case other => sys.error(s"Invalid TASTy version string: $expectedTastyVersion") + } + + if(isNightly) { + assert(tastyIsExperimental, "TASTY needs to be experimental in nightly builds") + val expectedTastyMinor = if(scalaPatch == 0) scalaMinor else scalaMinor + 1 + assert(tastyMinor == expectedTastyMinor, "Invalid TASTy minor version") + } + + if(isRelease) { + assert(scalaMinor == tastyMinor, "Minor versions of TASTY vesion and Scala version should match in release builds") + if (scalaIsRC && scalaPatch == 0) + assert(tastyIsExperimental, "TASTy should be experimental when releasing a new minor version RC") + else + assert(!tastyIsExperimental, "Stable version cannot use experimental TASTY") + } + } } object ScaladocConfigs {