diff --git a/project/plugins.sbt b/project/plugins.sbt index d417a058..21480e70 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,6 +5,7 @@ addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "2.0.3") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.13.0") addSbtPlugin("com.github.cb372" % "sbt-explicit-dependencies" % "0.3.1") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.4") // Versioning and Release Plugins addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.12.0") diff --git a/zio-sbt-ci/src/main/scala/zio/sbt/ZioSbtCiPlugin.scala b/zio-sbt-ci/src/main/scala/zio/sbt/ZioSbtCiPlugin.scala index fcd84923..42427e4c 100644 --- a/zio-sbt-ci/src/main/scala/zio/sbt/ZioSbtCiPlugin.scala +++ b/zio-sbt-ci/src/main/scala/zio/sbt/ZioSbtCiPlugin.scala @@ -88,6 +88,7 @@ object ZioSbtCiPlugin extends AutoPlugin { val ciBackgroundJobs: SettingKey[Seq[String]] = settingKey[Seq[String]]("Background jobs") val ciBuildJobs: SettingKey[Seq[Job]] = settingKey[Seq[Job]]("CI Build Jobs") val ciLintJobs: SettingKey[Seq[Job]] = settingKey[Seq[Job]]("CI Lint Jobs") + val ciCheckMima: SettingKey[Boolean] = settingKey[Boolean]("Enable Lint Job: Check binary compatibility") val ciTestJobs: SettingKey[Seq[Job]] = settingKey[Seq[Job]]("CI Test Jobs") val ciUpdateReadmeJobs: SettingKey[Seq[Job]] = settingKey[Seq[Job]]("CI Update Readme Jobs") val ciReleaseJobs: SettingKey[Seq[Job]] = settingKey[Seq[Job]]("CI Release Jobs") @@ -139,7 +140,6 @@ object ZioSbtCiPlugin extends AutoPlugin { val swapSizeGB = ciSwapSizeGB.value val setSwapSpace = SetSwapSpace.value val checkGithubWorkflow = ciCheckGithubWorkflowSteps.value - val lint = Lint.value Seq( Job( @@ -152,7 +152,9 @@ object ZioSbtCiPlugin extends AutoPlugin { CacheDependencies ) ++ checkGithubWorkflow.flatMap( _.flatten - ) ++ Seq(lint) + ) ++ + Seq(Lint.value) ++ + (if (ciCheckMima.value) Seq(CheckMima.value) else Seq.empty[Step.SingleStep]) ) ) } @@ -686,6 +688,7 @@ object ZioSbtCiPlugin extends AutoPlugin { ciDefaultJavaVersion := zio.sbt.JavaVersion.`17`, ciBuildJobs := buildJobs.value, ciLintJobs := lintJobs.value, + ciCheckMima := false, ciTestJobs := testJobs.value, ciUpdateReadmeJobs := updateReadmeJobs.value, ciReleaseJobs := releaseJobs.value, @@ -785,6 +788,17 @@ object ZioSbtCiPlugin extends AutoPlugin { ) } + lazy val CheckMima: Def.Initialize[Step.SingleStep] = Def.setting { + val backgroundJobs = ciBackgroundJobs.value + val prefixJobs = makePrefixJobs(backgroundJobs) + val isSingleBuild = IsSingleBuild.value + + Step.SingleStep( + name = "Check binary compatibility", + run = Some(prefixJobs + "sbt " + (if (isSingleBuild) "checkMima" else "+checkMima")) + ) + } + lazy val Release: Def.Initialize[SingleStep] = Def.setting { val backgroundJobs = ciBackgroundJobs.value diff --git a/zio-sbt-ecosystem/src/main/scala/zio/sbt/MimaSettings.scala b/zio-sbt-ecosystem/src/main/scala/zio/sbt/MimaSettings.scala new file mode 100644 index 00000000..68643b6e --- /dev/null +++ b/zio-sbt-ecosystem/src/main/scala/zio/sbt/MimaSettings.scala @@ -0,0 +1,40 @@ +/* + * Copyright 2022-2023 dev.zio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package zio.sbt + +import com.typesafe.tools.mima.plugin.MimaKeys._ +import sbt.Keys._ +import sbt._ +import sbtdynver.DynVerPlugin.autoImport.previousStableVersion + +import zio.sbt.BuildAssertions.Keys.isScalaJVM + +trait MimaSettings { + + lazy val checkMima: TaskKey[Unit] = taskKey[Unit]("Checks binary compatibility against previous versions.") + + def enableMimaSettings(failOnProblem: Boolean = true): Seq[Setting[_]] = + Def.settings( + checkMima := { if (isScalaJVM.value && !(checkMima / skip).value) mimaReportBinaryIssues.value else () }, + mimaFailOnProblem := failOnProblem, + mimaPreviousArtifacts := previousStableVersion.value + .map(organization.value %% moduleName.value % _) + .fold(Set.empty[ModuleID])(Set(_)), + mimaBinaryIssueFilters := Seq() + ) + +} diff --git a/zio-sbt-ecosystem/src/main/scala/zio/sbt/ZioSbtEcosystemPlugin.scala b/zio-sbt-ecosystem/src/main/scala/zio/sbt/ZioSbtEcosystemPlugin.scala index 24a71670..d1e69f27 100644 --- a/zio-sbt-ecosystem/src/main/scala/zio/sbt/ZioSbtEcosystemPlugin.scala +++ b/zio-sbt-ecosystem/src/main/scala/zio/sbt/ZioSbtEcosystemPlugin.scala @@ -19,6 +19,7 @@ package zio.sbt import scala.collection.immutable.ListMap import com.jsuereth.sbtpgp.SbtPgp.autoImport._ +import com.typesafe.tools.mima.plugin.MimaPlugin import de.heikoseeberger.sbtheader.HeaderPlugin import org.scalafmt.sbt.ScalafmtPlugin import sbt.Keys._ @@ -34,9 +35,9 @@ object ZioSbtEcosystemPlugin extends AutoPlugin { override def trigger = allRequirements override def requires: Plugins = - super.requires && HeaderPlugin && ScalafixPlugin && ScalafmtPlugin && BuildInfoPlugin && ZioSbtCrossbuildPlugin + super.requires && HeaderPlugin && ScalafixPlugin && ScalafmtPlugin && BuildInfoPlugin && ZioSbtCrossbuildPlugin && MimaPlugin - object autoImport extends ScalaCompilerSettings { + object autoImport extends ScalaCompilerSettings with MimaSettings { def addCommand(commandString: List[String], name: String, description: String): Seq[Setting[_]] = { val cCommand = Commands.ComposableCommand(commandString, name, description)