Repository: scala-steward-org/scala-steward
Pull request #3576 (2025-02-03 13:20:17)

Use `RepoConfig#signoffCommits` for migrations and hooks
This uses `RepoConfig#signoffCommits` for Scalafix migrations and post-update hooks commits and removes the `signoffCommits` fields from `PostUpdateHook` and `ScalafixMigration` (which were added in #3432). The latter fields concealed that `RepoConfig#signoffCommits` was partially ignored for post-update hooks and completely ignored for Scalafix migrations.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala
index f9aa60ee..ac0f33a1 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/EditAlg.scala
@@ -94,11 +94,8 @@ final class EditAlg[F[_]](implicit
       result <- logger.attemptWarn.log("Scalafix migration failed") {
         buildToolDispatcher.runMigration(repo, config, migration)
       }
-      maybeCommit <- gitAlg.commitAllIfDirty(
-        repo,
-        migration.commitMessage(result),
-        migration.signoffCommits
-      )
+      maybeCommit <-
+        gitAlg.commitAllIfDirty(repo, migration.commitMessage(result), config.signoffCommits)
     } yield ScalafixEdit(migration, result, maybeCommit)
 
   private def applyUpdateReplacements(
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
index 938b4554..67e2015e 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
@@ -46,9 +46,7 @@ final class HookExecutor[F[_]](implicit
     F: MonadThrow[F]
 ) {
   def execPostUpdateHooks(data: RepoData, update: Update.Single): F[List[EditAttempt]] =
-    (HookExecutor.postUpdateHooks(
-      data.config.signoffCommits
-    ) ++ data.config.postUpdateHooksOrDefault)
+    (HookExecutor.postUpdateHooks ++ data.config.postUpdateHooksOrDefault)
       .filter { hook =>
         hook.groupId.forall(update.groupId === _) &&
         hook.artifactId.forall(aid => update.artifactIds.exists(_.name === aid.name)) &&
@@ -56,12 +54,13 @@ final class HookExecutor[F[_]](implicit
         hook.enabledByConfig(data.config)
       }
       .distinctBy(_.command)
-      .traverse(execPostUpdateHook(data.repo, update, _))
+      .traverse(execPostUpdateHook(data.repo, update, _, data.config.signoffCommits))
 
   private def execPostUpdateHook(
       repo: Repo,
       update: Update.Single,
-      hook: PostUpdateHook
+      hook: PostUpdateHook,
+      signoffCommits: Option[Boolean]
   ): F[EditAttempt] =
     for {
       _ <- logger.info(
@@ -77,10 +76,10 @@ final class HookExecutor[F[_]](implicit
       commitMessage = hook
         .commitMessage(update)
         .appendParagraph(s"Executed command: ${hook.command.mkString_(" ")}")
-      maybeHookCommit <- gitAlg.commitAllIfDirty(repo, commitMessage, hook.signoffCommits)
+      maybeHookCommit <- gitAlg.commitAllIfDirty(repo, commitMessage, signoffCommits)
       maybeBlameIgnoreCommit <-
         maybeHookCommit.flatTraverse(
-          addToGitBlameIgnoreRevs(repo, repoDir, hook, _, commitMessage, hook.signoffCommits)
+          addToGitBlameIgnoreRevs(repo, repoDir, hook, _, commitMessage, signoffCommits)
         )
     } yield HookEdit(hook, result, maybeHookCommit.toList ++ maybeBlameIgnoreCommit.toList)
 
@@ -150,8 +149,7 @@ object HookExecutor {
   private def sbtGithubWorkflowGenerateHook(
       groupId: GroupId,
       artifactId: ArtifactId,
-      enabledByCache: RepoCache => Boolean,
-      signoffCommits: Option[Boolean]
+      enabledByCache: RepoCache => Boolean
   ): PostUpdateHook =
     PostUpdateHook(
       groupId = Some(groupId),
@@ -161,11 +159,10 @@ object HookExecutor {
       commitMessage = _ => CommitMsg("Regenerate GitHub Actions workflow"),
       enabledByCache = enabledByCache,
       enabledByConfig = _ => true,
-      addToGitBlameIgnoreRevs = false,
-      signoffCommits = signoffCommits
+      addToGitBlameIgnoreRevs = false
     )
 
-  private def scalafmtHook(signoffCommits: Option[Boolean]) =
+  private val scalafmtHook =
     PostUpdateHook(
       groupId = Some(scalafmtGroupId),
       artifactId = Some(scalafmtArtifactId),
@@ -174,14 +171,12 @@ object HookExecutor {
       commitMessage = update => CommitMsg(s"Reformat with scalafmt ${update.nextVersion}"),
       enabledByCache = _ => true,
       enabledByConfig = _.scalafmtOrDefault.runAfterUpgradingOrDefault,
-      addToGitBlameIgnoreRevs = true,
-      signoffCommits = signoffCommits
+      addToGitBlameIgnoreRevs = true
     )
 
   private def sbtTypelevelHook(
       groupId: GroupId,
-      artifactId: ArtifactId,
-      signoffCommits: Option[Boolean]
+      artifactId: ArtifactId
   ): PostUpdateHook =
     PostUpdateHook(
       groupId = Some(groupId),
@@ -191,22 +186,19 @@ object HookExecutor {
       commitMessage = _ => CommitMsg("Run prePR with sbt-typelevel"),
       enabledByCache = _ => true,
       enabledByConfig = _ => true,
-      addToGitBlameIgnoreRevs = false,
-      signoffCommits = signoffCommits
+      addToGitBlameIgnoreRevs = false
     )
 
   private def githubWorkflowGenerateExists(cache: RepoCache): Boolean =
     cache.dependsOn(sbtGitHubWorkflowGenerateModules ++ sbtTypelevelModules)
 
-  private def postUpdateHooks(signoffCommits: Option[Boolean]): List[PostUpdateHook] =
-    scalafmtHook(signoffCommits) ::
+  private val postUpdateHooks: List[PostUpdateHook] =
+    scalafmtHook ::
       sbtGitHubWorkflowGenerateModules.map { case (gid, aid) =>
-        sbtGithubWorkflowGenerateHook(gid, aid, _ => true, signoffCommits)
+        sbtGithubWorkflowGenerateHook(gid, aid, _ => true)
       } ++
       conditionalSbtGitHubWorkflowGenerateModules.map { case (gid, aid) =>
-        sbtGithubWorkflowGenerateHook(gid, aid, githubWorkflowGenerateExists, signoffCommits)
+        sbtGithubWorkflowGenerateHook(gid, aid, githubWorkflowGenerateExists)
       } ++
-      sbtTypelevelModules.map { case (gid, aid) =>
-        sbtTypelevelHook(gid, aid, signoffCommits)
-      }
+      sbtTypelevelModules.map { case (gid, aid) => sbtTypelevelHook(gid, aid) }
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/PostUpdateHook.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/PostUpdateHook.scala
index 5b2df5b6..599d8849 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/PostUpdateHook.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/PostUpdateHook.scala
@@ -31,8 +31,7 @@ final case class PostUpdateHook(
     commitMessage: Update.Single => CommitMsg,
     enabledByCache: RepoCache => Boolean,
     enabledByConfig: RepoConfig => Boolean,
-    addToGitBlameIgnoreRevs: Boolean,
-    signoffCommits: Option[Boolean]
+    addToGitBlameIgnoreRevs: Boolean
 ) {
   def showCommand: String = command.mkString_("'", " ", "'")
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigration.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigration.scala
index 62e76957..2a0dd35e 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigration.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigration.scala
@@ -34,8 +34,7 @@ final case class ScalafixMigration(
     scalacOptions: Option[Nel[String]] = None,
     authors: Option[Nel[Author]] = None,
     target: Option[Target] = None,
-    executionOrder: Option[ExecutionOrder] = None,
-    signoffCommits: Option[Boolean]
+    executionOrder: Option[ExecutionOrder] = None
 ) {
   def commitMessage(result: Either[Throwable, Unit]): CommitMsg = {
     val verb = if (result.isRight) "Applied" else "Failed"
diff --git a/modules/core/src/main/scala/org/scalasteward/core/repoconfig/PostUpdateHookConfig.scala b/modules/core/src/main/scala/org/scalasteward/core/repoconfig/PostUpdateHookConfig.scala
index e2cb19a6..d9073cd4 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/repoconfig/PostUpdateHookConfig.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/repoconfig/PostUpdateHookConfig.scala
@@ -28,8 +28,7 @@ final case class PostUpdateHookConfig(
     artifactId: Option[String],
     command: Nel[String],
     commitMessage: String,
-    addToGitBlameIgnoreRevs: Option[Boolean] = None,
-    signoffCommits: Option[Boolean]
+    addToGitBlameIgnoreRevs: Option[Boolean] = None
 ) {
   def toHook: PostUpdateHook =
     PostUpdateHook(
@@ -40,8 +39,7 @@ final case class PostUpdateHookConfig(
       commitMessage = CommitMsg.replaceVariables(commitMessage)(_, None),
       enabledByCache = _ => true,
       enabledByConfig = _ => true,
-      addToGitBlameIgnoreRevs = addToGitBlameIgnoreRevs.getOrElse(false),
-      signoffCommits = signoffCommits
+      addToGitBlameIgnoreRevs = addToGitBlameIgnoreRevs.getOrElse(false)
     )
 }
 


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
index 5f10b49f..fcf28bda 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
@@ -54,8 +54,7 @@ class SbtAlgTest extends FunSuite {
       GroupId("co.fs2"),
       Nel.of("fs2-core"),
       Version("1.0.0"),
-      Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5"),
-      signoffCommits = None
+      Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5")
     )
     val initialState = MockState.empty
       .addFiles(
@@ -94,8 +93,7 @@ class SbtAlgTest extends FunSuite {
       Nel.of("cats-core"),
       Version("2.2.0"),
       Nel.of("github:cb372/cats/Cats_v2_2_0?sha=235bd7c92e431ab1902db174cf4665b05e08f2f1"),
-      scalacOptions = Some(Nel.of("-P:semanticdb:synthetics:on")),
-      signoffCommits = None
+      scalacOptions = Some(Nel.of("-P:semanticdb:synthetics:on"))
     )
     val initialState = MockState.empty
       .addFiles(
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/scalacli/ScalaCliAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/scalacli/ScalaCliAlgTest.scala
index 0ad9aff9..f8ece208 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/scalacli/ScalaCliAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/scalacli/ScalaCliAlgTest.scala
@@ -91,8 +91,7 @@ class ScalaCliAlgTest extends CatsEffectSuite {
       GroupId("co.fs2"),
       Nel.of("fs2-core"),
       Version("1.0.0"),
-      Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5"),
-      signoffCommits = None
+      Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5")
     )
     val obtained = scalaCliAlg.runMigration(buildRoot, migration).runS(MockState.empty)
     val expected = MockState.empty.copy(trace =
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
index 37da0aa5..f323c827 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
@@ -126,8 +126,7 @@ class HookExecutorTest extends CatsEffectSuite {
           groupId = None,
           artifactId = None,
           command = Nel.of("sbt", "mySbtCommand"),
-          commitMessage = "Updated with a hook!",
-          signoffCommits = None
+          commitMessage = "Updated with a hook!"
         )
       ).some
     )
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala
index 61ed1308..f14a3dcb 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala
@@ -20,8 +20,7 @@ class ScalafixMigrationsFinderTest extends FunSuite {
           Some(
             "https://github.com/typelevel/cats/blob/v2.2.0/scalafix/README.md#migration-to-cats-v220"
           ),
-          Some(Nel.of("-P:semanticdb:synthetics:on")),
-          signoffCommits = None
+          Some(Nel.of("-P:semanticdb:synthetics:on"))
         )
       ),
       List()
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala
index 0074a43e..e1f35597 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsLoaderTest.scala
@@ -37,8 +37,7 @@ class ScalafixMigrationsLoaderTest extends FunSuite {
     Some("https://scalacenter.github.io/scalafix/"),
     authors = Some(Nel.of(Author("Jane Doe", "jane@example.com"))),
     target = Some(Sources),
-    executionOrder = Some(PreUpdate),
-    signoffCommits = None
+    executionOrder = Some(PreUpdate)
   )
 
   test("loadAll: without extra file, without defaults") {
diff --git a/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala b/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala
index 00a2323f..5bd5ed12 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala
@@ -101,8 +101,7 @@ class NewPullRequestDataTest extends FunSuite {
         groupId = "com.spotify".g,
         artifactIds = Nel.one("scio-core"),
         newVersion = Version("0.7.0"),
-        rewriteRules = Nel.of("I am a rewrite rule"),
-        signoffCommits = None
+        rewriteRules = Nel.of("I am a rewrite rule")
       ),
       result = Right(()),
       maybeCommit = Some(Commit(dummySha1))
@@ -464,8 +463,7 @@ class NewPullRequestDataTest extends FunSuite {
         "com.spotify".g,
         Nel.one("scio-core"),
         Version("0.7.0"),
-        Nel.of("I am a rewrite rule"),
-        signoffCommits = None
+        Nel.of("I am a rewrite rule")
       ),
       Right(()),
       Some(Commit(dummySha1))
@@ -495,8 +493,7 @@ class NewPullRequestDataTest extends FunSuite {
         Nel.one("scio-core"),
         Version("0.7.0"),
         Nel.of("I am a rewrite rule", "I am a 2nd rewrite rule"),
-        Some("https://scalacenter.github.io/scalafix/"),
-        signoffCommits = None
+        Some("https://scalacenter.github.io/scalafix/")
       ),
       Right(()),
       Some(Commit(dummySha1))
@@ -528,8 +525,7 @@ class NewPullRequestDataTest extends FunSuite {
         Nel.one("scio-core"),
         Version("0.7.0"),
         Nel.of("I am a rewrite rule", "I am a 2nd rewrite rule"),
-        Some("https://scalacenter.github.io/scalafix/"),
-        signoffCommits = None
+        Some("https://scalacenter.github.io/scalafix/")
       ),
       Right(()),
       Some(Commit(dummySha1))
@@ -539,8 +535,7 @@ class NewPullRequestDataTest extends FunSuite {
         "org.typeleve".g,
         Nel.of("cats-effect", "cats-effect-laws"),
         Version("3.0.0"),
-        Nel.of("I am a rule without an effect"),
-        signoffCommits = None
+        Nel.of("I am a rule without an effect")
       ),
       Right(()),
       None
@@ -623,8 +618,7 @@ class NewPullRequestDataTest extends FunSuite {
         Nel.one("scio-core"),
         Version("0.7.0"),
         Nel.of("I am a rewrite rule", "I am a 2nd rewrite rule"),
-        Some("https://scalacenter.github.io/scalafix/"),
-        signoffCommits = None
+        Some("https://scalacenter.github.io/scalafix/")
       ),
       Right(()),
       Some(Commit(dummySha1))
diff --git a/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala
index 8905053d..dd8580f0 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala
@@ -393,8 +393,7 @@ class RepoConfigAlgTest extends FunSuite {
           groupId = None,
           artifactId = None,
           command = Nel.of("sbt", "mySbtCommand"),
-          commitMessage = "Updated with a hook!",
-          signoffCommits = None
+          commitMessage = "Updated with a hook!"
         )
       ).some
     )
@@ -418,8 +417,7 @@ class RepoConfigAlgTest extends FunSuite {
           groupId = Some("eu.timepit".g),
           artifactId = Some("refined.1"),
           command = Nel.of("sbt", "mySbtCommand"),
-          commitMessage = "Updated with a hook!",
-          signoffCommits = None
+          commitMessage = "Updated with a hook!"
         )
       ).some
     )