From f0785bdfe2f61d612b65754ceac0331a1bef58ae Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 24 Sep 2026 14:19:56 +0200 Subject: [PATCH] Migrate to sbt 2.0.9 and sbt-softwaremill 3.0.1 - sbt 2.0.9, sbt-softwaremill 3.0.1 - common settings are now bare settings in build.sbt - updateDocs and compileDocumentation are defined on the root project only, so that mdoc runs once - kafka tests are forked, - tests which need a directory use a temporary one - CI: setup-sbt v1.5.10, `testFull` instead of `test` - scalafmt: scala3 dialect for *.sbt files (build.sbt reformatted accordingly) Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 6 +- .scalafmt.conf | 8 ++- build.sbt | 58 +++++++++---------- .../ox/flow/FlowCompanionIOOpsTest.scala | 2 +- .../test/scala/ox/flow/FlowIOOpsTest.scala | 2 +- project/build.properties | 2 +- project/plugins.sbt | 2 +- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 303f7572..aca550bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: distribution: 'temurin' java-version: ${{ matrix.java }} cache: 'sbt' - - uses: sbt/setup-sbt@3e125ece5c3e5248e18da9ed8d2cce3d335ec8dd # v1, specifically v1.1.14 + - uses: sbt/setup-sbt@ce95da69b39609ea153bad087708da5f37366897 # v1, specifically v1.5.10 - name: Check formatting run: sbt -v scalafmtCheckAll - name: Compile @@ -32,7 +32,7 @@ jobs: - name: Compile documentation run: sbt -v compileDocumentation - name: Test - run: sbt -v test + run: sbt -v testFull - uses: actions/upload-artifact@v4 # upload test results if: success() || failure() # run this step even if previous step failed with: @@ -65,4 +65,4 @@ jobs: if: github.event.pull_request.user.login == 'softwaremill-ci' needs: [ ci, label, mima ] uses: softwaremill/github-actions-workflows/.github/workflows/auto-merge.yml@main - secrets: inherit \ No newline at end of file + secrets: inherit diff --git a/.scalafmt.conf b/.scalafmt.conf index 0f35c332..ed0b17f7 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -6,4 +6,10 @@ rewrite.scala3 { convertToNewSyntax = true removeOptionalBraces.enabled = true insertEndMarkerMinLines = 8 -} \ No newline at end of file +} + +fileOverride { + "glob:**.sbt" { + runner.dialect = scala3 + } +} diff --git a/build.sbt b/build.sbt index 2f64c7b8..186fe4d8 100644 --- a/build.sbt +++ b/build.sbt @@ -3,34 +3,27 @@ import com.softwaremill.Publish.{ossPublishSettings, updateDocs} import com.softwaremill.UpdateVersionInDocs import com.typesafe.tools.mima.core.{MissingClassProblem, ProblemFilters} -lazy val commonSettings = commonSmlBuildSettings ++ ossPublishSettings ++ Seq( - organization := "com.softwaremill.ox", - scalaVersion := "3.3.8", - scalacOptions ++= Seq("-Yfuture-lazy-vals", "-java-output-version", "21"), - updateDocs := Def.taskDyn { - val files1 = UpdateVersionInDocs(sLog.value, organization.value, version.value) - Def.task { - (documentation / mdoc).toTask("").value - files1 ++ Seq(file("generated-doc/out")) - } - }.value, - Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.Assertion:s", - Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.compatible.Assertion:s", - mimaPreviousArtifacts := Set.empty // we only use MiMa for `core` for now, using enableMimaSettings -) +commonSmlBuildSettings +ossPublishSettings + +organization := "com.softwaremill.ox" +scalaVersion := "3.3.8" +scalacOptions ++= Seq("-Yfuture-lazy-vals", "-java-output-version", "21") +Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.Assertion:s" +Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.compatible.Assertion:s" +mimaPreviousArtifacts := Set.empty // we only use MiMa for `core` for now, using enableMimaSettings val enableMimaSettings = Seq( mimaPreviousArtifacts := { val current = version.value val isRcOrMilestone = current.contains("M") || current.contains("RC") - if (!isRcOrMilestone) { + if !isRcOrMilestone then val previous = previousStableVersion.value println(s"[info] Not a M or RC version, using previous version for MiMa check: $previous") previousStableVersion.value.map(organization.value %% moduleName.value % _).toSet - } else { + else println(s"[info] $current is an M or RC version, no previous version to check with MiMa") Set.empty - } }, mimaBinaryIssueFilters ++= Seq( // GroupingTimeout is only ever used within the groupWithin method, never exposed externally @@ -47,17 +40,23 @@ val jsoniterMacros = "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala- // used during CI to verify that the documentation compiles val compileDocumentation: TaskKey[Unit] = taskKey[Unit]("Compiles documentation throwing away its output") -compileDocumentation := { - (documentation / mdoc).toTask(" --out target/ox-doc").value -} lazy val rootProject = (project in file(".")) - .settings(commonSettings) - .settings(publishArtifact := false, name := "ox") + .settings( + publishArtifact := false, + name := "ox", + updateDocs := Def.uncached(Def.taskDyn { + val files1 = UpdateVersionInDocs(sLog.value, organization.value, version.value) + Def.task { + (documentation / mdoc).toTask("").value + files1 ++ Seq(file("generated-doc/out")) + } + }.value), + compileDocumentation := (documentation / mdoc).toTask(" --out target/ox-doc").value + ) .aggregate(core, kafka, mdcLogback, flowReactiveStreams, flowJson, cron, otelContext) lazy val core: Project = (project in file("core")) - .settings(commonSettings) .settings( name := "core", libraryDependencies ++= Seq( @@ -71,7 +70,6 @@ lazy val core: Project = (project in file("core")) .settings(enableMimaSettings) lazy val kafka: Project = (project in file("kafka")) - .settings(commonSettings) .settings( name := "kafka", libraryDependencies ++= Seq( @@ -82,12 +80,13 @@ lazy val kafka: Project = (project in file("kafka")) "org.apache.pekko" %% "pekko-connectors-kafka" % "1.2.0" % Test, "org.apache.pekko" %% "pekko-stream" % "1.7.0" % Test, scalaTest - ) + ), + // in sbt 2's default (client) mode tests would hang in sbt 2.0.9 + Test / fork := true ) .dependsOn(core) lazy val mdcLogback: Project = (project in file("mdc-logback")) - .settings(commonSettings) .settings( name := "mdc-logback", libraryDependencies ++= Seq( @@ -98,7 +97,6 @@ lazy val mdcLogback: Project = (project in file("mdc-logback")) .dependsOn(core) lazy val flowReactiveStreams: Project = (project in file("flow-reactive-streams")) - .settings(commonSettings) .settings( name := "flow-reactive-streams", libraryDependencies ++= Seq( @@ -109,7 +107,6 @@ lazy val flowReactiveStreams: Project = (project in file("flow-reactive-streams" .dependsOn(core) lazy val flowJson: Project = (project in file("flow-json")) - .settings(commonSettings) .settings( name := "flow-json", libraryDependencies ++= Seq( @@ -121,7 +118,6 @@ lazy val flowJson: Project = (project in file("flow-json")) .dependsOn(core) lazy val cron: Project = (project in file("cron")) - .settings(commonSettings) .settings( name := "cron", libraryDependencies ++= Seq( @@ -132,7 +128,6 @@ lazy val cron: Project = (project in file("cron")) .dependsOn(core % "test->test;compile->compile") lazy val otelContext: Project = (project in file("otel-context")) - .settings(commonSettings) .settings( name := "otel-context", libraryDependencies ++= Seq( @@ -144,7 +139,6 @@ lazy val otelContext: Project = (project in file("otel-context")) lazy val documentation: Project = (project in file("generated-doc")) // important: it must not be doc/ .enablePlugins(MdocPlugin) - .settings(commonSettings) .settings( mdocIn := file("doc"), moduleName := "ox-doc", diff --git a/core/src/test/scala/ox/flow/FlowCompanionIOOpsTest.scala b/core/src/test/scala/ox/flow/FlowCompanionIOOpsTest.scala index f093d1b5..6ad4a908 100644 --- a/core/src/test/scala/ox/flow/FlowCompanionIOOpsTest.scala +++ b/core/src/test/scala/ox/flow/FlowCompanionIOOpsTest.scala @@ -60,7 +60,7 @@ class FlowCompanionIOOpsTest extends AnyWordSpec with Matchers: assertThrows[NoSuchFileException](Flow.fromFile(path).runToList()) "throw an exception if path is a directory" in supervised: - val path = Paths.get(getClass.getResource("/").toURI) + val path = Files.createTempDirectory("ox-test") val exception = intercept[IOException](Flow.fromFile(path).runToList()) exception.getMessage should endWith("is a directory") diff --git a/core/src/test/scala/ox/flow/FlowIOOpsTest.scala b/core/src/test/scala/ox/flow/FlowIOOpsTest.scala index eff4bb8a..01054e0f 100644 --- a/core/src/test/scala/ox/flow/FlowIOOpsTest.scala +++ b/core/src/test/scala/ox/flow/FlowIOOpsTest.scala @@ -404,7 +404,7 @@ class FlowIOOpsTest extends AnyWordSpec with Matchers: exception.getMessage shouldBe "expected source error" "throw an exception if path is a directory" in: - val path = Paths.get(getClass.getResource("/").toURI) + val path = Files.createTempDirectory("ox-test") val source = Flow.fromValues(Chunk.empty[Byte]) val exception = intercept[IOException](source.runToFile(path)) exception.getMessage should endWith("is a directory") diff --git a/project/build.properties b/project/build.properties index e0a1aa02..ddca111e 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.13.0 +sbt.version=2.0.9 diff --git a/project/plugins.sbt b/project/plugins.sbt index be6da1ee..154cf3db 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -val sbtSoftwareMillVersion = "2.1.2" +val sbtSoftwareMillVersion = "3.0.1" addSbtPlugin("com.softwaremill.sbt-softwaremill" % "sbt-softwaremill-common" % sbtSoftwareMillVersion) addSbtPlugin("com.softwaremill.sbt-softwaremill" % "sbt-softwaremill-publish" % sbtSoftwareMillVersion) addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.9.2")