Repository: scala-steward-org/scala-steward
Pull request #3432 (2024-10-09 16:55:05)

Add repo-specific signoff option

michaelmior: @mzuehlke Good call on that change! I amended my previous commit to include that.

Patch:
diff --git a/docs/repo-specific-configuration.md b/docs/repo-specific-configuration.md
index 2098c66a..9555ac16 100644
--- a/docs/repo-specific-configuration.md
+++ b/docs/repo-specific-configuration.md
@@ -184,6 +184,10 @@ dependencyOverrides = [
 # to add assignees or request reviews. Consequently, it won't work for public @scala-steward instance on GitHub.
 assignees = [ "username1", "username2" ]
 reviewers = [ "username1", "username2" ]
+
+# If true, Scala Steward will sign off all commits (e.g. `git --signoff`).
+# Default: false
+signoffCommits = true
 ```
 
 The version information given in the patterns above can be in two formats:
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 f4692919..614b76d1 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,7 +94,11 @@ final class EditAlg[F[_]](implicit
       result <- logger.attemptWarn.log("Scalafix migration failed") {
         buildToolDispatcher.runMigration(repo, config, migration)
       }
-      maybeCommit <- gitAlg.commitAllIfDirty(repo, migration.commitMessage(result))
+      maybeCommit <- gitAlg.commitAllIfDirty(
+        repo,
+        migration.commitMessage(result),
+        migration.signoffCommits
+      )
     } yield ScalafixEdit(migration, result, maybeCommit)
 
   private def applyUpdateReplacements(
@@ -111,7 +115,7 @@ final class EditAlg[F[_]](implicit
       _ <- reformatChangedFiles(data)
       msgTemplate = data.config.commits.messageOrDefault
       commitMsg = CommitMsg.replaceVariables(msgTemplate)(update, data.repo.branch)
-      maybeCommit <- gitAlg.commitAllIfDirty(data.repo, commitMsg)
+      maybeCommit <- gitAlg.commitAllIfDirty(data.repo, commitMsg, data.config.signoffCommits)
     } yield maybeCommit.map(UpdateEdit(update, _))
 
   private def reformatChangedFiles(data: RepoData): F[Unit] = {
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 3687eba7..d3f3d850 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,7 +46,9 @@ final class HookExecutor[F[_]](implicit
     F: MonadThrow[F]
 ) {
   def execPostUpdateHooks(data: RepoData, update: Update.Single): F[List[EditAttempt]] =
-    (HookExecutor.postUpdateHooks ++ data.config.postUpdateHooksOrDefault)
+    (HookExecutor.postUpdateHooks(
+      data.config.signoffCommits
+    ) ++ data.config.postUpdateHooksOrDefault)
       .filter { hook =>
         hook.groupId.forall(update.groupId === _) &&
         hook.artifactId.forall(aid => update.artifactIds.exists(_.name === aid.name)) &&
@@ -75,9 +77,11 @@ final class HookExecutor[F[_]](implicit
       commitMessage = hook
         .commitMessage(update)
         .appendParagraph(s"Executed command: ${hook.command.mkString_(" ")}")
-      maybeHookCommit <- gitAlg.commitAllIfDirty(repo, commitMessage)
+      maybeHookCommit <- gitAlg.commitAllIfDirty(repo, commitMessage, hook.signoffCommits)
       maybeBlameIgnoreCommit <-
-        maybeHookCommit.flatTraverse(addToGitBlameIgnoreRevs(repo, repoDir, hook, _, commitMessage))
+        maybeHookCommit.flatTraverse(
+          addToGitBlameIgnoreRevs(repo, repoDir, hook, _, commitMessage, hook.signoffCommits)
+        )
     } yield HookEdit(hook, result, maybeHookCommit.toList ++ maybeBlameIgnoreCommit.toList)
 
   private def addToGitBlameIgnoreRevs(
@@ -85,7 +89,8 @@ final class HookExecutor[F[_]](implicit
       repoDir: File,
       hook: PostUpdateHook,
       commit: Commit,
-      commitMsg: CommitMsg
+      commitMsg: CommitMsg,
+      signoffCommits: Option[Boolean]
   ): F[Option[Commit]] =
     if (hook.addToGitBlameIgnoreRevs) {
       for {
@@ -100,7 +105,7 @@ final class HookExecutor[F[_]](implicit
         addAndCommit = gitAlg.add(repo, pathAsString).flatMap { _ =>
           val blameIgnoreCommitMsg =
             CommitMsg(s"Add '${commitMsg.title}' to $gitBlameIgnoreRevsName")
-          gitAlg.commitAllIfDirty(repo, blameIgnoreCommitMsg)
+          gitAlg.commitAllIfDirty(repo, blameIgnoreCommitMsg, signoffCommits)
         }
         maybeBlameIgnoreCommit <- gitAlg
           .checkIgnore(repo, pathAsString)
@@ -145,7 +150,8 @@ object HookExecutor {
   private def sbtGithubWorkflowGenerateHook(
       groupId: GroupId,
       artifactId: ArtifactId,
-      enabledByCache: RepoCache => Boolean
+      enabledByCache: RepoCache => Boolean,
+      signoffCommits: Option[Boolean]
   ): PostUpdateHook =
     PostUpdateHook(
       groupId = Some(groupId),
@@ -155,10 +161,11 @@ object HookExecutor {
       commitMessage = _ => CommitMsg("Regenerate GitHub Actions workflow"),
       enabledByCache = enabledByCache,
       enabledByConfig = _ => true,
-      addToGitBlameIgnoreRevs = false
+      addToGitBlameIgnoreRevs = false,
+      signoffCommits = signoffCommits
     )
 
-  private val scalafmtHook =
+  private def scalafmtHook(signoffCommits: Option[Boolean]) =
     PostUpdateHook(
       groupId = Some(scalafmtGroupId),
       artifactId = Some(scalafmtArtifactId),
@@ -167,12 +174,14 @@ object HookExecutor {
       commitMessage = update => CommitMsg(s"Reformat with scalafmt ${update.nextVersion}"),
       enabledByCache = _ => true,
       enabledByConfig = _.scalafmt.runAfterUpgradingOrDefault,
-      addToGitBlameIgnoreRevs = true
+      addToGitBlameIgnoreRevs = true,
+      signoffCommits = signoffCommits
     )
 
   private def sbtTypelevelHook(
       groupId: GroupId,
-      artifactId: ArtifactId
+      artifactId: ArtifactId,
+      signoffCommits: Option[Boolean]
   ): PostUpdateHook =
     PostUpdateHook(
       groupId = Some(groupId),
@@ -182,21 +191,22 @@ object HookExecutor {
       commitMessage = _ => CommitMsg("Run prePR with sbt-typelevel"),
       enabledByCache = _ => true,
       enabledByConfig = _ => true,
-      addToGitBlameIgnoreRevs = false
+      addToGitBlameIgnoreRevs = false,
+      signoffCommits = signoffCommits
     )
 
   private def githubWorkflowGenerateExists(cache: RepoCache): Boolean =
     cache.dependsOn(sbtGitHubWorkflowGenerateModules ++ sbtTypelevelModules)
 
-  private val postUpdateHooks: List[PostUpdateHook] =
-    scalafmtHook ::
+  private def postUpdateHooks(signoffCommits: Option[Boolean]): List[PostUpdateHook] =
+    scalafmtHook(signoffCommits) ::
       sbtGitHubWorkflowGenerateModules.map { case (gid, aid) =>
-        sbtGithubWorkflowGenerateHook(gid, aid, _ => true)
+        sbtGithubWorkflowGenerateHook(gid, aid, _ => true, signoffCommits)
       } ++
       conditionalSbtGitHubWorkflowGenerateModules.map { case (gid, aid) =>
-        sbtGithubWorkflowGenerateHook(gid, aid, githubWorkflowGenerateExists)
+        sbtGithubWorkflowGenerateHook(gid, aid, githubWorkflowGenerateExists, signoffCommits)
       } ++
       sbtTypelevelModules.map { case (gid, aid) =>
-        sbtTypelevelHook(gid, aid)
+        sbtTypelevelHook(gid, aid, signoffCommits)
       }
 }
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 c0dc69c5..9fff88b9 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,7 +31,8 @@ final case class PostUpdateHook(
     commitMessage: Update.Single => CommitMsg,
     enabledByCache: RepoCache => Boolean,
     enabledByConfig: RepoConfig => Boolean,
-    addToGitBlameIgnoreRevs: Boolean
+    addToGitBlameIgnoreRevs: Boolean,
+    signoffCommits: Option[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 63990803..3952b7f9 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,7 +34,8 @@ final case class ScalafixMigration(
     scalacOptions: Option[Nel[String]] = None,
     authors: Option[Nel[Author]] = None,
     target: Option[Target] = None,
-    executionOrder: Option[ExecutionOrder] = None
+    executionOrder: Option[ExecutionOrder] = None,
+    signoffCommits: Option[Boolean]
 ) {
   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/git/FileGitAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala
index 0a51ed11..fd96bec2 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/git/FileGitAlg.scala
@@ -63,10 +63,16 @@ final class FileGitAlg[F[_]](config: GitCfg)(implicit
   override def cloneExists(repo: File): F[Boolean] =
     fileAlg.isDirectory(repo / ".git")
 
-  override def commitAll(repo: File, message: CommitMsg): F[Commit] = {
+  override def commitAll(
+      repo: File,
+      message: CommitMsg,
+      signoffCommits: Option[Boolean]
+  ): F[Commit] = {
     val messages = message.paragraphs.foldMap(m => List("-m", m))
     val trailers = message.trailers.foldMap { case (k, v) => List("--trailer", s"$k=$v") }
-    git_("commit" :: "--all" :: sign :: signoff :: messages ++ trailers: _*)(repo) >>
+    git_("commit" :: "--all" :: sign :: signoff(signoffCommits) :: messages ++ trailers: _*)(
+      repo
+    ) >>
       latestSha1(repo, Branch.head).map(Commit.apply)
   }
 
@@ -171,8 +177,8 @@ final class FileGitAlg[F[_]](config: GitCfg)(implicit
   private val sign: String =
     if (config.signCommits) "--gpg-sign" else "--no-gpg-sign"
 
-  private val signoff: String =
-    if (config.signoff) "--signoff" else "--no-signoff"
+  private def signoff(signoffCommits: Option[Boolean]): String =
+    if (signoffCommits.getOrElse(config.signoff)) "--signoff" else "--no-signoff"
 }
 
 object FileGitAlg {
diff --git a/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala
index deae9c40..f8f65075 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/git/GenGitAlg.scala
@@ -40,7 +40,7 @@ trait GenGitAlg[F[_], Repo] {
 
   def cloneExists(repo: Repo): F[Boolean]
 
-  def commitAll(repo: Repo, message: CommitMsg): F[Commit]
+  def commitAll(repo: Repo, message: CommitMsg, signoffCommits: Option[Boolean]): F[Commit]
 
   def containsChanges(repo: Repo): F[Boolean]
 
@@ -78,10 +78,13 @@ trait GenGitAlg[F[_], Repo] {
 
   def version: F[String]
 
-  final def commitAllIfDirty(repo: Repo, message: CommitMsg)(implicit
-      F: Monad[F]
+  final def commitAllIfDirty(repo: Repo, message: CommitMsg, signoffCommits: Option[Boolean])(
+      implicit F: Monad[F]
   ): F[Option[Commit]] =
-    containsChanges(repo).ifM(commitAll(repo, message).map(Some.apply), F.pure(None))
+    containsChanges(repo).ifM(
+      commitAll(repo, message, signoffCommits).map(Some.apply),
+      F.pure(None)
+    )
 
   final def returnToCurrentBranch[A, E](repo: Repo)(fa: F[A])(implicit F: MonadCancel[F, E]): F[A] =
     F.bracket(currentBranch(repo))(_ => fa)(checkoutBranch(repo, _))
@@ -113,8 +116,12 @@ trait GenGitAlg[F[_], Repo] {
       override def cloneExists(repo: A): F[Boolean] =
         f(repo).flatMap(self.cloneExists)
 
-      override def commitAll(repo: A, message: CommitMsg): F[Commit] =
-        f(repo).flatMap(self.commitAll(_, message))
+      override def commitAll(
+          repo: A,
+          message: CommitMsg,
+          signoffCommits: Option[Boolean]
+      ): F[Commit] =
+        f(repo).flatMap(self.commitAll(_, message, signoffCommits))
 
       override def containsChanges(repo: A): F[Boolean] =
         f(repo).flatMap(self.containsChanges)
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 fb9bbbda..07725422 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
@@ -29,7 +29,8 @@ final case class PostUpdateHookConfig(
     artifactId: Option[String],
     command: Nel[String],
     commitMessage: String,
-    addToGitBlameIgnoreRevs: Option[Boolean] = None
+    addToGitBlameIgnoreRevs: Option[Boolean] = None,
+    signoffCommits: Option[Boolean]
 ) {
   def toHook: PostUpdateHook =
     PostUpdateHook(
@@ -40,7 +41,8 @@ final case class PostUpdateHookConfig(
       commitMessage = CommitMsg.replaceVariables(commitMessage)(_, None),
       enabledByCache = _ => true,
       enabledByConfig = _ => true,
-      addToGitBlameIgnoreRevs = addToGitBlameIgnoreRevs.getOrElse(false)
+      addToGitBlameIgnoreRevs = addToGitBlameIgnoreRevs.getOrElse(false),
+      signoffCommits = signoffCommits
     )
 }
 
diff --git a/modules/core/src/main/scala/org/scalasteward/core/repoconfig/RepoConfig.scala b/modules/core/src/main/scala/org/scalasteward/core/repoconfig/RepoConfig.scala
index 6e3f81db..46b20122 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/repoconfig/RepoConfig.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/repoconfig/RepoConfig.scala
@@ -37,7 +37,8 @@ final case class RepoConfig(
     buildRoots: Option[List[BuildRootConfig]] = None,
     assignees: List[String] = List.empty,
     reviewers: List[String] = List.empty,
-    dependencyOverrides: List[GroupRepoConfig] = List.empty
+    dependencyOverrides: List[GroupRepoConfig] = List.empty,
+    signoffCommits: Option[Boolean] = None
 ) {
   def buildRootsOrDefault(repo: Repo): List[BuildRoot] =
     buildRoots
@@ -88,7 +89,8 @@ object RepoConfig {
               buildRoots = x.buildRoots |+| y.buildRoots,
               assignees = x.assignees |+| y.assignees,
               reviewers = x.reviewers |+| y.reviewers,
-              dependencyOverrides = x.dependencyOverrides |+| y.dependencyOverrides
+              dependencyOverrides = x.dependencyOverrides |+| y.dependencyOverrides,
+              signoffCommits = x.signoffCommits.orElse(y.signoffCommits)
             )
         }
     )
diff --git a/modules/docs/mdoc/repo-specific-configuration.md b/modules/docs/mdoc/repo-specific-configuration.md
index 6d461495..99eeef0e 100644
--- a/modules/docs/mdoc/repo-specific-configuration.md
+++ b/modules/docs/mdoc/repo-specific-configuration.md
@@ -190,6 +190,10 @@ dependencyOverrides = [
 # to add assignees or request reviews. Consequently, it won't work for public @scala-steward instance on GitHub.
 assignees = [ "username1", "username2" ]
 reviewers = [ "username1", "username2" ]
+
+# If true, Scala Steward will sign off all commits (e.g. `git --signoff`).
+# Default: false
+signoffCommits = true
 """)
 println("```")
 ```


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 f065d891..2baff720 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,7 +54,8 @@ 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")
+      Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5"),
+      signoffCommits = None
     )
     val initialState = MockState.empty
       .addFiles(
@@ -93,7 +94,8 @@ 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"))
+      scalacOptions = Some(Nel.of("-P:semanticdb:synthetics:on")),
+      signoffCommits = None
     )
     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 7852ee9e..5d8266d7 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,7 +91,8 @@ 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")
+      Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5"),
+      signoffCommits = None
     )
     val obtained = scalaCliAlg.runMigration(buildRoot, migration).runS(MockState.empty)
     assertIO(obtained.map(_.trace.collect { case Log(_) => () }.size), 1)
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 ab6539c4..7aa0de4a 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,7 +126,8 @@ class HookExecutorTest extends CatsEffectSuite {
           groupId = None,
           artifactId = None,
           command = Nel.of("sbt", "mySbtCommand"),
-          commitMessage = "Updated with a hook!"
+          commitMessage = "Updated with a hook!",
+          signoffCommits = None
         )
       ).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 829751cf..f7686102 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,7 +20,8 @@ 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"))
+          Some(Nel.of("-P:semanticdb:synthetics:on")),
+          signoffCommits = None
         )
       ),
       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 733dc72b..eda6b030 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
@@ -36,7 +36,8 @@ 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)
+    executionOrder = Some(PreUpdate),
+    signoffCommits = None
   )
 
   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 821d0d99..ca72e2cb 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
@@ -72,7 +72,8 @@ 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")
+        rewriteRules = Nel.of("I am a rewrite rule"),
+        signoffCommits = None
       ),
       result = Right(()),
       maybeCommit = Some(Commit(dummySha1))
@@ -317,7 +318,8 @@ class NewPullRequestDataTest extends FunSuite {
         "com.spotify".g,
         Nel.one("scio-core"),
         Version("0.7.0"),
-        Nel.of("I am a rewrite rule")
+        Nel.of("I am a rewrite rule"),
+        signoffCommits = None
       ),
       Right(()),
       Some(Commit(dummySha1))
@@ -347,7 +349,8 @@ 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/")
+        Some("https://scalacenter.github.io/scalafix/"),
+        signoffCommits = None
       ),
       Right(()),
       Some(Commit(dummySha1))
@@ -379,7 +382,8 @@ 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/")
+        Some("https://scalacenter.github.io/scalafix/"),
+        signoffCommits = None
       ),
       Right(()),
       Some(Commit(dummySha1))
@@ -389,7 +393,8 @@ 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")
+        Nel.of("I am a rule without an effect"),
+        signoffCommits = None
       ),
       Right(()),
       None
@@ -472,7 +477,8 @@ 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/")
+        Some("https://scalacenter.github.io/scalafix/"),
+        signoffCommits = None
       ),
       Right(()),
       Some(Commit(dummySha1))
diff --git a/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala
index 88206b5b..2d3561f2 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/git/FileGitAlgTest.scala
@@ -83,10 +83,10 @@ class FileGitAlgTest extends CatsEffectSuite {
       b1 <- ioGitAlg.branchesDiffer(repo, bar, foo)
       _ <- ioFileAlg.writeFile(repo / "test.txt", "hello")
       _ <- ioAuxGitAlg.git("add", "test.txt")(repo)
-      _ <- ioGitAlg.commitAll(repo, CommitMsg("Add test.txt"))
+      _ <- ioGitAlg.commitAll(repo, CommitMsg("Add test.txt"), signoffCommits = None)
       b2 <- ioGitAlg.branchesDiffer(repo, foo, bar)
       _ <- ioAuxGitAlg.git("rm", "test.txt")(repo)
-      _ <- ioGitAlg.commitAll(repo, CommitMsg("Remove test.txt"))
+      _ <- ioGitAlg.commitAll(repo, CommitMsg("Remove test.txt"), signoffCommits = None)
       b3 <- ioGitAlg.branchesDiffer(repo, foo, bar)
       _ = assertEquals((b1, b2, b3), (false, true, false))
     } yield ()
@@ -110,12 +110,12 @@ class FileGitAlgTest extends CatsEffectSuite {
       _ <- ioAuxGitAlg.createRepo(repo)
       _ <- ioFileAlg.writeFile(repo / "test.txt", "hello")
       _ <- ioAuxGitAlg.git("add", "test.txt")(repo)
-      _ <- ioGitAlg.commitAll(repo, CommitMsg("Add test.txt"))
+      _ <- ioGitAlg.commitAll(repo, CommitMsg("Add test.txt"), signoffCommits = None)
       c1 <- ioGitAlg.containsChanges(repo)
       _ <- ioFileAlg.writeFile(repo / "test.txt", "hello world")
       c2 <- ioGitAlg.containsChanges(repo)
       m2 = CommitMsg("Modify test.txt", coAuthoredBy = List(Author("name", "email")))
-      _ <- ioGitAlg.commitAllIfDirty(repo, m2)
+      _ <- ioGitAlg.commitAllIfDirty(repo, m2, signoffCommits = None)
       c3 <- ioGitAlg.containsChanges(repo)
       _ = assertEquals((c1, c2, c3), (false, true, false))
     } yield ()
@@ -138,7 +138,7 @@ class FileGitAlgTest extends CatsEffectSuite {
       file = repo / "test.txt"
       _ <- ioFileAlg.writeFile(file, "hello")
       _ <- ioAuxGitAlg.git("add", "test.txt")(repo)
-      _ <- ioGitAlg.commitAll(repo, CommitMsg("Add test.txt"))
+      _ <- ioGitAlg.commitAll(repo, CommitMsg("Add test.txt"), signoffCommits = None)
       _ <- ioFileAlg.writeFile(file, "world")
       before <- ioFileAlg.readFile(file)
       _ <- ioGitAlg.discardChanges(repo)
@@ -228,7 +228,7 @@ object FileGitAlgTest {
     def addFiles(repo: File, files: File*): F[Unit] =
       files.toList.traverse_ { file =>
         git("add", file.pathAsString)(repo) >>
-          gitAlg.commitAll(repo, CommitMsg(s"Add ${file.name}"))
+          gitAlg.commitAll(repo, CommitMsg(s"Add ${file.name}"), signoffCommits = None)
       }
 
     def createConflict(repo: File): F[Unit] =
@@ -241,18 +241,22 @@ object FileGitAlgTest {
         _ <- gitAlg.createBranch(repo, conflictsNo)
         _ <- fileAlg.writeFile(repo / "file3", "file3, line1")
         _ <- git("add", "file3")(repo)
-        _ <- gitAlg.commitAll(repo, CommitMsg("Add file3 on conflicts-no"))
+        _ <- gitAlg.commitAll(repo, CommitMsg("Add file3 on conflicts-no"), signoffCommits = None)
         _ <- gitAlg.checkoutBranch(repo, master)
         // work on conflicts-yes
         _ <- gitAlg.createBranch(repo, conflictsYes)
         _ <- fileAlg.writeFile(repo / "file2", "file2, line1\nfile2, line2 on conflicts-yes")
         _ <- git("add", "file2")(repo)
-        _ <- gitAlg.commitAll(repo, CommitMsg("Modify file2 on conflicts-yes"))
+        _ <- gitAlg.commitAll(
+          repo,
+          CommitMsg("Modify file2 on conflicts-yes"),
+          signoffCommits = None
+        )
         _ <- gitAlg.checkoutBranch(repo, master)
         // work on master
         _ <- fileAlg.writeFile(repo / "file2", "file2, line1\nfile2, line2 on master")
         _ <- git("add", "file2")(repo)
-        _ <- gitAlg.commitAll(repo, CommitMsg("Modify file2 on master"))
+        _ <- gitAlg.commitAll(repo, CommitMsg("Modify file2 on master"), signoffCommits = None)
       } yield ()
 
     def createConflictFileRemovedOnMaster(repo: File): F[Unit] =
@@ -265,12 +269,16 @@ object FileGitAlgTest {
         _ <- gitAlg.createBranch(repo, conflictsYes)
         _ <- fileAlg.writeFile(repo / "file2", "file2, line1\nfile2, line2 on conflicts-yes")
         _ <- git("add", "file2")(repo)
-        _ <- gitAlg.commitAll(repo, CommitMsg("Modify file2 on conflicts-yes"))
+        _ <- gitAlg.commitAll(
+          repo,
+          CommitMsg("Modify file2 on conflicts-yes"),
+          signoffCommits = None
+        )
         _ <- gitAlg.checkoutBranch(repo, master)
         // work on master
         _ <- git("rm", "file2")(repo)
         _ <- git("add", "-A")(repo)
-        _ <- gitAlg.commitAll(repo, CommitMsg("Remove file2 on master"))
+        _ <- gitAlg.commitAll(repo, CommitMsg("Remove file2 on master"), signoffCommits = None)
       } yield ()
   }
 
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 fb620b74..b63b789f 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
@@ -390,7 +390,8 @@ class RepoConfigAlgTest extends FunSuite {
           groupId = None,
           artifactId = None,
           command = Nel.of("sbt", "mySbtCommand"),
-          commitMessage = "Updated with a hook!"
+          commitMessage = "Updated with a hook!",
+          signoffCommits = None
         )
       ).some
     )
@@ -414,7 +415,8 @@ class RepoConfigAlgTest extends FunSuite {
           groupId = Some("eu.timepit".g),
           artifactId = Some("refined.1"),
           command = Nel.of("sbt", "mySbtCommand"),
-          commitMessage = "Updated with a hook!"
+          commitMessage = "Updated with a hook!",
+          signoffCommits = None
         )
       ).some
     )