diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fa3fd20..8b8d7332 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: os: [ubuntu-latest] scala: [2.12.15] java: [temurin@8] - ci: [ciJVM] + project: [rootJVM] runs-on: ${{ matrix.os }} steps: - name: Checkout current branch (full) @@ -57,9 +57,19 @@ jobs: key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - name: Check that workflows are up to date - run: sbt '++${{ matrix.scala }}' 'project /' githubWorkflowCheck + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' 'project /' githubWorkflowCheck - - run: sbt '++${{ matrix.scala }}' '${{ matrix.ci }}' + - name: Check headers and formatting + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' headerCheckAll scalafmtCheckAll 'project /' scalafmtSbtCheck + + - name: Test + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' test + + - name: Check binary compatibility + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' mimaReportBinaryIssues + + - name: Generate API documentation + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' doc - name: Make target directories run: mkdir -p github/target github-actions/target kernel/target versioning/target ci-release/target target .js/target ci-signing/target mima/target .jvm/target .native/target no-publish/target sonatype/target ci/target sonatype-ci-release/target core/target settings/target project/target @@ -129,4 +139,5 @@ jobs: echo "$PGP_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg (echo "$PGP_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1) - - run: sbt '++${{ matrix.scala }}' tlRelease + - name: Publish + run: sbt '++${{ matrix.scala }}' tlRelease diff --git a/README.md b/README.md index f5d208be..ef0ccf02 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Instead of using the super-plugins, for finer-grained control you can always add - Requires `PGP_SECRET` secret, with your base64-encoded PGP key - Optionally set the `PGP_PASSPHRASE` secret, but we do not recommend passphrase-protected keys for new projects. See discussion in [#9](https://github.com/typelevel/sbt-typelevel/discussions/9#discussioncomment-1251774). - **sbt-typelevel-ci-release**, `TypelevelCiReleasePlugin`: The super-plugin that sets you up with versioning, mima, signing, and sonatype publishing, all in GitHub actions. -- **sbt-typelevel**, `TypelevelPlugin`: The super-super-plugin intended for bootstrapping the typical Typelevel project. Sets up CI release, scalac settings, headers, and formatting. +- **sbt-typelevel**, `TypelevelPlugin`: The super-super-plugin intended for bootstrapping the typical Typelevel project. Sets up CI release including snapshots, scalac settings, headers, and formatting. - `tlFatalWarningsInCi` (setting): Convert compiler warnings into errors under CI builds (default: true). ### Dependency diagram diff --git a/ci-signing/src/main/scala/org/typelevel/sbt/TypelevelCiSigningPlugin.scala b/ci-signing/src/main/scala/org/typelevel/sbt/TypelevelCiSigningPlugin.scala index aa22069a..c6ffed9b 100644 --- a/ci-signing/src/main/scala/org/typelevel/sbt/TypelevelCiSigningPlugin.scala +++ b/ci-signing/src/main/scala/org/typelevel/sbt/TypelevelCiSigningPlugin.scala @@ -33,7 +33,7 @@ object TypelevelCiSigningPlugin extends AutoPlugin { "PGP_SECRET" -> s"$${{ secrets.PGP_SECRET }}", "PGP_PASSPHRASE" -> s"$${{ secrets.PGP_PASSPHRASE }}" ), - githubWorkflowPublishPreamble ++= Seq( + githubWorkflowPublishPreamble := Seq( WorkflowStep.Run( // if your key is not passphrase-protected List("echo $PGP_SECRET | base64 -d | gpg --import"), name = Some("Import signing key"), diff --git a/ci/src/main/scala/org/typelevel/sbt/CrossRootProject.scala b/ci/src/main/scala/org/typelevel/sbt/CrossRootProject.scala index 7483ed8e..d9362bcf 100644 --- a/ci/src/main/scala/org/typelevel/sbt/CrossRootProject.scala +++ b/ci/src/main/scala/org/typelevel/sbt/CrossRootProject.scala @@ -18,8 +18,6 @@ package org.typelevel.sbt import sbt._ import org.typelevel.sbt.gha.GenerativePlugin.autoImport._ -import TypelevelCiPlugin.ciCommands -import TypelevelKernelPlugin.mkCommand /** * Simultaneously creates a `root`, `rootJVM`, `rootJS`, and `rootNative` project, and @@ -113,12 +111,8 @@ object TypelevelCiCrossPlugin extends AutoPlugin { override def requires = TypelevelCiPlugin override def buildSettings = Seq( - githubWorkflowBuild ~= { steps => - // remove the usual ci step and replace with matrix ci - steps.diff(Seq(WorkflowStep.Sbt(List("ci")))) :+ - WorkflowStep.Sbt(List(s"$${{ matrix.ci }}")) - }, - githubWorkflowBuildMatrixAdditions += "ci" -> Nil + githubWorkflowBuildSbtStepPreamble ~= { s"project $${{ matrix.project }}" +: _ }, + githubWorkflowBuildMatrixAdditions += "project" -> Nil ) } @@ -127,56 +121,66 @@ object TypelevelCiCrossPlugin extends AutoPlugin { object TypelevelCiJVMPlugin extends AutoPlugin { override def requires = TypelevelCiCrossPlugin - override def buildSettings: Seq[Setting[_]] = - addCommandAlias("ciJVM", mkCommand(ciJVMCommands)) ++ Seq( - githubWorkflowBuildMatrixAdditions ~= { matrix => - matrix.updated("ci", matrix("ci") ::: "ciJVM" :: Nil) - } - ) - - val ciJVMCommands = "project rootJVM" :: ciCommands.tail + override def buildSettings: Seq[Setting[_]] = Seq( + githubWorkflowBuildMatrixAdditions ~= { matrix => + matrix.updated("project", matrix("project") ::: "rootJVM" :: Nil) + } + ) } object TypelevelCiJSPlugin extends AutoPlugin { override def requires = TypelevelCiCrossPlugin - override def buildSettings: Seq[Setting[_]] = - addCommandAlias("ciJS", mkCommand(ciJSCommands)) ++ Seq( - githubWorkflowBuildMatrixAdditions ~= { matrix => - matrix.updated("ci", matrix("ci") ::: "ciJS" :: Nil) - }, - githubWorkflowBuildMatrixExclusions ++= { - githubWorkflowJavaVersions - .value - .tail - .map(java => MatrixExclude(Map("ci" -> "ciJS", "java" -> java.render))) + override def buildSettings: Seq[Setting[_]] = Seq( + githubWorkflowBuildMatrixAdditions ~= { matrix => + matrix.updated("project", matrix("project") ::: "rootJS" :: Nil) + }, + githubWorkflowBuildMatrixExclusions ++= { + githubWorkflowJavaVersions + .value + .tail + .map(java => MatrixExclude(Map("project" -> "rootJS", "java" -> java.render))) + }, + githubWorkflowBuild ~= { steps => + steps.flatMap { + case testStep @ WorkflowStep.Sbt(List("test"), _, _, _, _, _) => + val fastOptStep = WorkflowStep.Sbt( + List("Test/fastOptJS"), + name = Some("fastOptJS"), + cond = Some("matrix.project == 'rootJS'") + ) + List(fastOptStep, testStep) + case step => List(step) } - ) + } + ) - val ciJSCommands = "project rootJS" :: ciCommands.tail.flatMap { - case "test" => List("Test/fastOptJS", "test") - case x => List(x) - } } object TypelevelCiNativePlugin extends AutoPlugin { override def requires = TypelevelCiCrossPlugin - override def buildSettings: Seq[Setting[_]] = - addCommandAlias("ciNative", mkCommand(ciNativeCommands)) ++ Seq( - githubWorkflowBuildMatrixAdditions ~= { matrix => - matrix.updated("ci", matrix("ci") ::: "ciNative" :: Nil) - }, - githubWorkflowBuildMatrixExclusions ++= { - githubWorkflowJavaVersions - .value - .tail - .map(java => MatrixExclude(Map("ci" -> "ciNative", "java" -> java.render))) + override def buildSettings: Seq[Setting[_]] = Seq( + githubWorkflowBuildMatrixAdditions ~= { matrix => + matrix.updated("project", matrix("project") ::: "rootNative" :: Nil) + }, + githubWorkflowBuildMatrixExclusions ++= { + githubWorkflowJavaVersions + .value + .tail + .map(java => MatrixExclude(Map("project" -> "rootNative", "java" -> java.render))) + }, + githubWorkflowBuild ~= { steps => + steps.flatMap { + case testStep @ WorkflowStep.Sbt(List("test"), _, _, _, _, _) => + val nativeLinkStep = WorkflowStep.Sbt( + List("Test/nativeLink"), + name = Some("nativeLink"), + cond = Some("matrix.project == 'rootNative'") + ) + List(nativeLinkStep, testStep) + case step => List(step) } - ) - - val ciNativeCommands = "project rootNative" :: ciCommands.tail.flatMap { - case "test" => List("Test/nativeLink", "test") - case x => List(x) - } + } + ) } diff --git a/ci/src/main/scala/org/typelevel/sbt/TypelevelCiPlugin.scala b/ci/src/main/scala/org/typelevel/sbt/TypelevelCiPlugin.scala index b4ee0391..4df6c20e 100644 --- a/ci/src/main/scala/org/typelevel/sbt/TypelevelCiPlugin.scala +++ b/ci/src/main/scala/org/typelevel/sbt/TypelevelCiPlugin.scala @@ -21,7 +21,6 @@ import org.typelevel.sbt.gha.GenerativePlugin import org.typelevel.sbt.gha.GitHubActionsPlugin import org.typelevel.sbt.gha.GenerativePlugin.autoImport._ import com.typesafe.tools.mima.plugin.MimaPlugin -import TypelevelKernelPlugin.mkCommand object TypelevelCiPlugin extends AutoPlugin { @@ -32,18 +31,17 @@ object TypelevelCiPlugin extends AutoPlugin { def tlCrossRootProject: CrossRootProject = CrossRootProject() } - override def buildSettings = - addCommandAlias("ci", mkCommand(ciCommands)) ++ Seq( - githubWorkflowPublishTargetBranches := Seq(), - githubWorkflowBuild := Seq(WorkflowStep.Sbt(List("ci"))), - githubWorkflowJavaVersions := Seq(JavaSpec.temurin("8")) - ) - - val ciCommands = List( - "project /", - "clean", - "test", - "mimaReportBinaryIssues" + override def buildSettings = Seq( + githubWorkflowPublishTargetBranches := Seq(), + githubWorkflowBuild := Seq( + WorkflowStep.Sbt(List("test"), name = Some("Test")), + WorkflowStep.Sbt( + List("mimaReportBinaryIssues"), + name = Some("Check binary compatibility") + ), + WorkflowStep.Sbt(List("doc"), name = Some("Generate API documentation")) + ), + githubWorkflowJavaVersions := Seq(JavaSpec.temurin("8")) ) } diff --git a/core/src/main/scala/org/typelevel/sbt/TypelevelPlugin.scala b/core/src/main/scala/org/typelevel/sbt/TypelevelPlugin.scala index 40146f3b..fe83865a 100644 --- a/core/src/main/scala/org/typelevel/sbt/TypelevelPlugin.scala +++ b/core/src/main/scala/org/typelevel/sbt/TypelevelPlugin.scala @@ -20,8 +20,6 @@ import sbt._, Keys._ import org.typelevel.sbt.gha.GenerativePlugin import org.typelevel.sbt.gha.GitHubActionsPlugin import de.heikoseeberger.sbtheader.AutomateHeaderPlugin -import TypelevelCiPlugin.ciCommands -import TypelevelKernelPlugin.mkCommand object TypelevelPlugin extends AutoPlugin { @@ -39,7 +37,6 @@ object TypelevelPlugin extends AutoPlugin { } import autoImport._ - import TypelevelKernelPlugin.autoImport._ import TypelevelSettingsPlugin.autoImport._ import TypelevelSonatypeCiReleasePlugin.autoImport._ import GenerativePlugin.autoImport._ @@ -62,38 +59,15 @@ object TypelevelPlugin extends AutoPlugin { scala <- githubWorkflowScalaVersions.value.init java <- githubWorkflowJavaVersions.value.tail } yield MatrixExclude(Map("scala" -> scala, "java" -> java.render)) + }, + githubWorkflowBuild ~= { steps => + WorkflowStep.Sbt( + List("headerCheckAll", "scalafmtCheckAll", "project /", "scalafmtSbtCheck"), + name = Some("Check headers and formatting") + ) +: steps } - ) ++ tlReplaceCommandAlias("ci", mkCommand(fmtCheckCommands ::: ciCommands.tail)) + ) override def projectSettings = AutomateHeaderPlugin.projectSettings - val fmtCheckCommands = - List("project /", "headerCheckAll", "scalafmtCheckAll", "scalafmtSbtCheck") -} - -import TypelevelKernelPlugin.autoImport._ -import TypelevelPlugin.fmtCheckCommands -import TypelevelCiJVMPlugin.ciJVMCommands -import TypelevelCiJSPlugin.ciJSCommands -import TypelevelCiNativePlugin.ciNativeCommands - -object TypelevelJVMPlugin extends AutoPlugin { - override def requires = TypelevelCiJVMPlugin - override def trigger = allRequirements - override def buildSettings = - tlReplaceCommandAlias("ciJVM", mkCommand(fmtCheckCommands ++ ciJVMCommands)) -} - -object TypelevelJSPlugin extends AutoPlugin { - override def requires = TypelevelCiJSPlugin - override def trigger = allRequirements - override def buildSettings = - tlReplaceCommandAlias("ciJS", mkCommand(fmtCheckCommands ++ ciJSCommands)) -} - -object TypelevelNativePlugin extends AutoPlugin { - override def requires = TypelevelCiNativePlugin - override def trigger = allRequirements - override def buildSettings = - tlReplaceCommandAlias("ciNative", mkCommand(fmtCheckCommands ++ ciNativeCommands)) } diff --git a/sonatype-ci-release/src/main/scala/org/typelevel/sbt/TypelevelSonatypeCiReleasePlugin.scala b/sonatype-ci-release/src/main/scala/org/typelevel/sbt/TypelevelSonatypeCiReleasePlugin.scala index 99e73cc8..abf17803 100644 --- a/sonatype-ci-release/src/main/scala/org/typelevel/sbt/TypelevelSonatypeCiReleasePlugin.scala +++ b/sonatype-ci-release/src/main/scala/org/typelevel/sbt/TypelevelSonatypeCiReleasePlugin.scala @@ -59,7 +59,7 @@ object TypelevelSonatypeCiReleasePlugin extends AutoPlugin { }, githubWorkflowTargetTags += "v*", githubWorkflowPublish := Seq( - WorkflowStep.Sbt(List("tlRelease")) + WorkflowStep.Sbt(List("tlRelease"), name = Some("Publish")) ) ) }