diff --git a/build.sbt b/build.sbt index 382d1b00..b85d4c3e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,7 @@ name := "sbt-typelevel" import org.typelevel.sbt.gha.{PermissionScope, PermissionValue, Permissions} +import com.typesafe.tools.mima.core._ ThisBuild / tlBaseVersion := "0.7" ThisBuild / crossScalaVersions := Seq("2.12.20") @@ -121,7 +122,11 @@ lazy val githubActions = project .in(file("github-actions")) .enablePlugins(SbtPlugin) .settings( - name := "sbt-typelevel-github-actions" + name := "sbt-typelevel-github-actions", + mimaBinaryIssueFilters ++= Seq( + ProblemFilters.exclude[DirectMissingMethodProblem]("org.typelevel.sbt.gha.*#*#Impl.*"), + ProblemFilters.exclude[MissingTypesProblem]("org.typelevel.sbt.gha.*$*$Impl$") + ) ) lazy val mergify = project diff --git a/github-actions/src/main/scala/org/typelevel/sbt/gha/GenerativePlugin.scala b/github-actions/src/main/scala/org/typelevel/sbt/gha/GenerativePlugin.scala index 625809f9..b6763f89 100644 --- a/github-actions/src/main/scala/org/typelevel/sbt/gha/GenerativePlugin.scala +++ b/github-actions/src/main/scala/org/typelevel/sbt/gha/GenerativePlugin.scala @@ -264,6 +264,7 @@ ${indent(rendered.mkString("\n"), 1)}""" val renderedId = step.id.map(wrap).map("id: " + _ + "\n").getOrElse("") val renderedCond = step.cond.map(wrap).map("if: " + _ + "\n").getOrElse("") val renderedShell = if (declareShell) "shell: bash\n" else "" + val renderedContinueOnError = if (step.continueOnError) "continue-on-error: true\n" else "" val renderedEnvPre = compileEnv(step.env) val renderedEnv = @@ -288,7 +289,12 @@ ${indent(rendered.mkString("\n"), 1)}""" case run: Run => val renderedWorkingDirectory = run.workingDirectory.map(wrap).map("working-directory: " + _ + "\n").getOrElse("") - renderRunBody(run.commands, run.params, renderedShell, renderedWorkingDirectory) + renderRunBody( + run.commands, + run.params, + renderedShell, + renderedWorkingDirectory, + renderedContinueOnError) case sbtStep: Sbt => import sbtStep.commands @@ -312,7 +318,8 @@ ${indent(rendered.mkString("\n"), 1)}""" commands = List(s"$sbt $safeCommands"), params = sbtStep.params, renderedShell = renderedShell, - renderedWorkingDirectory = "" + renderedWorkingDirectory = "", + renderedContinueOnError = renderedContinueOnError ) case use: Use => @@ -338,18 +345,27 @@ ${indent(rendered.mkString("\n"), 1)}""" s"uses: docker://$image:$tag" } - decl + renderParams(params) + decl + renderedContinueOnError + renderParams(params) } indent(preamble + body, 1).updated(0, '-') } + @deprecated("Use the apply method with renderedContinueOnError", since = "0.7.8") + def renderRunBody( + commands: List[String], + params: Map[String, String], + renderedShell: String, + renderedWorkingDirectory: String): String = + renderRunBody(commands, params, renderedShell, renderedWorkingDirectory, "") + def renderRunBody( commands: List[String], params: Map[String, String], renderedShell: String, - renderedWorkingDirectory: String) = - renderedShell + renderedWorkingDirectory + "run: " + wrap( + renderedWorkingDirectory: String, + renderedContinueOnError: String): String = + renderedShell + renderedWorkingDirectory + renderedContinueOnError + "run: " + wrap( commands.mkString("\n")) + renderParams(params) def renderParams(params: Map[String, String]): String = { diff --git a/github-actions/src/main/scala/org/typelevel/sbt/gha/WorkflowStep.scala b/github-actions/src/main/scala/org/typelevel/sbt/gha/WorkflowStep.scala index 19d549d2..8660adf2 100644 --- a/github-actions/src/main/scala/org/typelevel/sbt/gha/WorkflowStep.scala +++ b/github-actions/src/main/scala/org/typelevel/sbt/gha/WorkflowStep.scala @@ -22,12 +22,14 @@ sealed abstract class WorkflowStep extends Product with Serializable { def cond: Option[String] def env: Map[String, String] def timeoutMinutes: Option[Int] + def continueOnError: Boolean def withId(id: Option[String]): WorkflowStep def withName(name: Option[String]): WorkflowStep def withCond(cond: Option[String]): WorkflowStep def withEnv(env: Map[String, String]): WorkflowStep def withTimeoutMinutes(minutes: Option[Int]): WorkflowStep + def withContinueOnError(continueOnError: Boolean): WorkflowStep def updatedEnv(name: String, value: String): WorkflowStep def concatEnv(env: TraversableOnce[(String, String)]): WorkflowStep @@ -136,6 +138,28 @@ object WorkflowStep { } object Run { + @deprecated("Use the apply method with continueOnError", since = "0.7.8") + def apply( + commands: List[String], + id: Option[String], + name: Option[String], + cond: Option[String], + env: Map[String, String], + params: Map[String, String], + timeoutMinutes: Option[Int], + workingDirectory: Option[String] + ): Run = apply( + commands, + id, + name, + cond, + env, + params, + timeoutMinutes, + workingDirectory, + continueOnError = false + ) + def apply( commands: List[String], id: Option[String] = None, @@ -144,8 +168,18 @@ object WorkflowStep { env: Map[String, String] = Map(), params: Map[String, String] = Map(), timeoutMinutes: Option[Int] = None, - workingDirectory: Option[String] = None): Run = - Impl(commands, id, name, cond, env, params, timeoutMinutes, workingDirectory) + workingDirectory: Option[String] = None, + continueOnError: Boolean = false): Run = + Impl( + commands, + id, + name, + cond, + env, + params, + timeoutMinutes, + workingDirectory, + continueOnError) private final case class Impl( commands: List[String], @@ -155,7 +189,8 @@ object WorkflowStep { env: Map[String, String], params: Map[String, String], timeoutMinutes: Option[Int], - workingDirectory: Option[String]) + workingDirectory: Option[String], + continueOnError: Boolean) extends Run { override def productPrefix = "Run" // scalafmt: { maxColumn = 200 } @@ -164,6 +199,7 @@ object WorkflowStep { def withCond(cond: Option[String]) = copy(cond = cond) def withEnv(env: Map[String, String]) = copy(env = env) def withTimeoutMinutes(minutes: Option[Int]) = copy(timeoutMinutes = minutes) + def withContinueOnError(continueOnError: Boolean) = copy(continueOnError = continueOnError) def withCommands(commands: List[String]) = copy(commands = commands) def withParams(params: Map[String, String]) = copy(params = params) @@ -193,6 +229,19 @@ object WorkflowStep { } object Sbt { + + @deprecated("Use the apply method with continueOnError", since = "0.7.8") + def apply( + commands: List[String], + id: Option[String], + name: Option[String], + cond: Option[String], + env: Map[String, String], + params: Map[String, String], + timeoutMinutes: Option[Int], + preamble: Boolean): Sbt = + apply(commands, id, name, cond, env, params, timeoutMinutes, preamble, false) + def apply( commands: List[String], id: Option[String] = None, @@ -201,8 +250,9 @@ object WorkflowStep { env: Map[String, String] = Map(), params: Map[String, String] = Map(), timeoutMinutes: Option[Int] = None, - preamble: Boolean = true): Sbt = - Impl(commands, id, name, cond, env, params, timeoutMinutes, preamble) + preamble: Boolean = true, + continueOnError: Boolean = false): Sbt = + Impl(commands, id, name, cond, env, params, timeoutMinutes, preamble, continueOnError) private final case class Impl( commands: List[String], @@ -212,7 +262,8 @@ object WorkflowStep { env: Map[String, String], params: Map[String, String], timeoutMinutes: Option[Int], - preamble: Boolean) + preamble: Boolean, + continueOnError: Boolean) extends Sbt { override def productPrefix = "Sbt" // scalafmt: { maxColumn = 200 } @@ -221,6 +272,7 @@ object WorkflowStep { def withCond(cond: Option[String]) = copy(cond = cond) def withEnv(env: Map[String, String]) = copy(env = env) def withTimeoutMinutes(minutes: Option[Int]) = copy(timeoutMinutes = minutes) + def withContinueOnError(continueOnError: Boolean): WorkflowStep = copy(continueOnError = continueOnError) def withCommands(commands: List[String]) = copy(commands = commands) def withParams(params: Map[String, String]) = copy(params = params) @@ -249,6 +301,27 @@ object WorkflowStep { object Use { + @deprecated("Use the apply method with continueOnError", since = "0.7.8") + def apply( + ref: UseRef, + params: Map[String, String], + id: Option[String], + name: Option[String], + cond: Option[String], + env: Map[String, String], + timeoutMinutes: Option[Int] + ): Use = + apply( + ref, + params, + id, + name, + cond, + env, + timeoutMinutes, + continueOnError = false + ) + def apply( ref: UseRef, params: Map[String, String] = Map(), @@ -256,8 +329,9 @@ object WorkflowStep { name: Option[String] = None, cond: Option[String] = None, env: Map[String, String] = Map(), - timeoutMinutes: Option[Int] = None): Use = - Impl(ref, params, id, name, cond, env, timeoutMinutes) + timeoutMinutes: Option[Int] = None, + continueOnError: Boolean = false): Use = + Impl(ref, params, id, name, cond, env, timeoutMinutes, continueOnError) private final case class Impl( ref: UseRef, @@ -266,7 +340,8 @@ object WorkflowStep { name: Option[String], cond: Option[String], env: Map[String, String], - timeoutMinutes: Option[Int]) + timeoutMinutes: Option[Int], + continueOnError: Boolean) extends Use { override def productPrefix = "Use" // scalafmt: { maxColumn = 200 } @@ -275,6 +350,7 @@ object WorkflowStep { def withCond(cond: Option[String]) = copy(cond = cond) def withEnv(env: Map[String, String]) = copy(env = env) def withTimeoutMinutes(minutes: Option[Int]) = copy(timeoutMinutes = minutes) + def withContinueOnError(continueOnError: Boolean) = copy(continueOnError = continueOnError) def withRef(ref: UseRef) = copy(ref = ref) def withParams(params: Map[String, String]) = copy(params = params)