Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to sbt-typelevel-ci-release #63

Merged
merged 8 commits into from
Jan 22, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 55 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ on:
tags: [v*]

env:
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
PGP_SECRET: ${{ secrets.PGP_SECRET }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
Expand All @@ -26,7 +30,7 @@ jobs:
os: [ubuntu-latest]
scala: [3.1.0]
java: [temurin@8]
platform: [jvm, js, native]
project: [rootJS, rootJVM, rootNative]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout current branch (full)
Expand Down Expand Up @@ -54,24 +58,41 @@ 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 }} githubWorkflowCheck
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' 'project /' githubWorkflowCheck

- name: Validate JVM
if: matrix.platform == 'jvm'
run: sbt ++${{ matrix.scala }} validateJVM
- name: fastOptJS
if: matrix.project == 'rootJS'
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/fastOptJS

- name: Validate JS
if: matrix.platform == 'js'
run: sbt ++${{ matrix.scala }} validateJS
- name: nativeLink
if: matrix.project == 'rootNative'
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/nativeLink

- name: Validate Native
if: matrix.platform == 'native'
run: sbt ++${{ matrix.scala }} validateNative
- 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 modules/deriving/.js/target modules/test/.jvm/target modules/test/.native/target target .js/target modules/typeable/.js/target modules/deriving/.jvm/target modules/typeable/.native/target .jvm/target .native/target local/.native/target local/.js/target modules/test/.js/target modules/typeable/.jvm/target local/.jvm/target modules/deriving/.native/target project/target

- name: Compress target directories
run: tar cf targets.tar modules/deriving/.js/target modules/test/.jvm/target modules/test/.native/target target .js/target modules/typeable/.js/target modules/deriving/.jvm/target modules/typeable/.native/target .jvm/target .native/target local/.native/target local/.js/target modules/test/.js/target modules/typeable/.jvm/target local/.jvm/target modules/deriving/.native/target project/target

- name: Upload target directories
uses: actions/upload-artifact@v2
with:
name: target-${{ matrix.os }}-${{ matrix.scala }}-${{ matrix.java }}
path: targets.tar
Comment on lines +79 to +89
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this running on PR?

Copy link
Member Author

@armanbilge armanbilge Jan 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. It's not harmful but probably not necessary. We can fix this upstream.


publish:
name: Publish Artifacts
needs: [build]
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
strategy:
matrix:
os: [ubuntu-latest]
Expand Down Expand Up @@ -103,11 +124,26 @@ jobs:
~/Library/Caches/Coursier/v1
key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}

- uses: olafurpg/setup-gpg@v3
- name: Download target directories (3.1.0)
uses: actions/download-artifact@v2
with:
name: target-${{ matrix.os }}-3.1.0-${{ matrix.java }}

- name: Inflate target directories (3.1.0)
run: |
tar xf targets.tar
rm targets.tar

- name: Import signing key
if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == ''
run: echo $PGP_SECRET | base64 -d | gpg --import

- name: Import signing key and strip passphrase
if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != ''
run: |
echo "$PGP_SECRET" | base64 -d > /tmp/signing-key.gpg
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)

- env:
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
PGP_SECRET: ${{ secrets.PGP_SECRET }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
run: sbt ++${{ matrix.scala }} ci-release
- name: Publish
run: sbt '++${{ matrix.scala }}' tlRelease
103 changes: 22 additions & 81 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,24 @@ import com.typesafe.tools.mima.core.{ProblemFilters, ReversedMissingMethodProble
val scala3Version = "3.1.0"

ThisBuild / organization := "org.typelevel"
ThisBuild / tlBaseVersion := "3.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for? Do we have to bump it after releasing 3.1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's part of the versioning scheme inherited from sbt-spiewak.
https://github.com/djspiewak/sbt-spiewak/blob/main/versioning.md#compatibility-version

Actually, you should bump it at the time you introduce "3.1-worthy" changes. E.g. if you follow strict semver and only do bugfixes in 3.0.x, your first PR adding a new feature should bump tlBaseVersion to 3.1. This is not enforced, but it's good practice and it makes sure all snapshots from that point are versioned with 3.1-hash-SNAPSHOT.

tlBaseVersion is also important if you ever decide you want to make breaking changes. At that point you would bump it to 4.0, and this would indicate to MiMa to stop checking bincompat against the 3.x artifacts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks for explaining - I think we should be already on 3.1 (since Scala native forces us to use Scala 3.1) but that can be bumped later as well.

ThisBuild / scalaVersion := scala3Version
ThisBuild / crossScalaVersions := Seq(scala3Version)
ThisBuild / mimaFailOnNoPrevious := false
ThisBuild / updateOptions := updateOptions.value.withLatestSnapshots(false)

val previousVersion = "3.0.0"

// GHA configuration

ThisBuild / githubWorkflowJavaVersions := List(JavaSpec.temurin("8"))
ThisBuild / githubWorkflowArtifactUpload := false
ThisBuild / tlCiReleaseBranches := Seq("main")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets up snapshots on main.

ThisBuild / githubWorkflowBuildMatrixFailFast := Some(false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this? It seems like it's the only setting left from githubWorkflow

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is None which is essentially true—fail fast is enabled (the first failing job cancels the rest). Up to you how you want to run your build :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove it 😄


val JvmCond = s"matrix.platform == 'jvm'"
val JsCond = s"matrix.platform == 'js'"
val NativeCond = s"matrix.platform == 'native'"

ThisBuild / githubWorkflowBuild := Seq(
WorkflowStep.Sbt(List("validateJVM"), name = Some("Validate JVM"), cond = Some(JvmCond)),
WorkflowStep.Sbt(List("validateJS"), name = Some("Validate JS"), cond = Some(JsCond)),
WorkflowStep.Sbt(List("validateNative"), name = Some("Validate Native"), cond = Some(NativeCond)),
)

ThisBuild / githubWorkflowTargetTags ++= Seq("v*")
ThisBuild / githubWorkflowPublishTargetBranches :=
Seq(RefPredicate.Equals(Ref.Branch("main")), RefPredicate.StartsWith(Ref.Tag("v")))

ThisBuild / githubWorkflowBuildMatrixAdditions +=
"platform" -> List("jvm", "js", "native")

ThisBuild / githubWorkflowPublishPreamble +=
WorkflowStep.Use(UseRef.Public("olafurpg", "setup-gpg", "v3"))

ThisBuild / githubWorkflowPublish := Seq(
WorkflowStep.Sbt(
List("ci-release"),
env = Map(
"PGP_PASSPHRASE" -> "${{ secrets.PGP_PASSPHRASE }}",
"PGP_SECRET" -> "${{ secrets.PGP_SECRET }}",
"SONATYPE_PASSWORD" -> "${{ secrets.SONATYPE_PASSWORD }}",
"SONATYPE_USERNAME" -> "${{ secrets.SONATYPE_USERNAME }}"
)
)
val jsSettings = Def.settings(
tlVersionIntroduced := Map("3" -> "3.0.1")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The Scala 3 cross-build was introduced in version 3.0.1 of my project". Most projects are using it to indicate when they added Scala 3. Here, since you added the Scala.js cross in v3.0.1 it goes in JS settings. It tells MiMa how far back to look for artifacts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so when we publish with Scala native we can make it a common setting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think this can ever be a common setting. Your JVM cross-build was introduced in 3.0.0, your JS cross-build was introduced in 3.0.1, and your Native cross-build will be introduced in 3.?.?. So they are all different.

)

val nativeSettings = Def.settings(
libraryDependencies += "org.scala-native" %%% "junit-runtime" % nativeVersion % Test,
addCompilerPlugin("org.scala-native" % "junit-plugin" % nativeVersion cross CrossVersion.full),
testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-s", "-v"),
mimaPreviousArtifacts := Set.empty,
)

// Aliases
Expand All @@ -72,20 +41,11 @@ addCommandAlias("testNative", ";derivingNative/test;testNative/test;typeableNati

// Projects

lazy val root = project
.in(file("."))
.settings(commonSettings)
.settings(crossScalaVersions := Seq())
.settings(noPublishSettings)
lazy val root = tlCrossRootProject
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This automatically sets up the CI matrix for JVM/JS/Native.

.aggregate(
derivingJVM,
derivingJS,
derivingNative,
testJVM,
testJS,
testNative,
typeableJVM,
typeableJS
deriving,
test,
typeable
)

lazy val deriving = crossProject(JSPlatform, JVMPlatform, NativePlatform)
Expand All @@ -98,6 +58,7 @@ lazy val deriving = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.platformsSettings(JVMPlatform, JSPlatform)(
libraryDependencies += "org.typelevel" %%% "cats-core" % "2.7.0" % "test",
)
.jsSettings(jsSettings)
.nativeSettings(
nativeSettings,
Test / sources := {
Expand All @@ -114,16 +75,14 @@ lazy val deriving = crossProject(JSPlatform, JVMPlatform, NativePlatform)
},
)
.settings(commonSettings)
.settings(mimaSettings)
.settings(
mimaBinaryIssueFilters ++= Seq(
ProblemFilters.exclude[ReversedMissingMethodProblem]("shapeless3.deriving.internals.ErasedInstances.erasedMapK"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("shapeless3.deriving.internals.ErasedProductInstances.erasedProject"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("shapeless3.deriving.internals.ErasedProductInstances.erasedMapK")
)
)
.settings(publishSettings)
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
.jsEnablePlugins(ScalaJSJUnitPlugin)

lazy val derivingJVM = deriving.jvm
lazy val derivingJS = deriving.js
Expand All @@ -136,10 +95,9 @@ lazy val test = crossProject(JSPlatform, JVMPlatform, NativePlatform)
moduleName := "shapeless3-test"
)
.settings(commonSettings)
.settings(mimaSettings)
.settings(publishSettings)
.jsSettings(jsSettings)
.nativeSettings(nativeSettings)
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
.jsEnablePlugins(ScalaJSJUnitPlugin)

lazy val testJVM = test.jvm
lazy val testJS = test.js
Expand All @@ -153,10 +111,9 @@ lazy val typeable = crossProject(JSPlatform, JVMPlatform, NativePlatform)
moduleName := "shapeless3-typeable"
)
.settings(commonSettings)
//.settings(mimaSettings) // Not yet
.settings(publishSettings)
.settings(mimaPreviousArtifacts := Set.empty) // Not yet
.nativeSettings(nativeSettings)
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
.jsEnablePlugins(ScalaJSJUnitPlugin)

lazy val typeableJVM = typeable.jvm
lazy val typeableJS = typeable.js
Expand All @@ -174,14 +131,12 @@ lazy val local = crossProject(JSPlatform, JVMPlatform, NativePlatform)
console / initialCommands := """import shapeless3.deriving.* ; import scala.deriving.*"""
)
.settings(commonSettings)
.settings(noPublishSettings)
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
.enablePlugins(NoPublishPlugin)
.jsEnablePlugins(ScalaJSJUnitPlugin)

// Settings

lazy val commonSettings = Seq(
crossScalaVersions := (ThisBuild / crossScalaVersions).value,

scalacOptions ++= Seq(
"-Xfatal-warnings",
"-Yexplicit-nulls"
Expand All @@ -191,23 +146,9 @@ lazy val commonSettings = Seq(
libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % "test",
)

lazy val mimaSettings = Seq(
mimaPreviousArtifacts := Set("org.typelevel" %% moduleName.value % previousVersion),
mimaBinaryIssueFilters := Seq()
)

lazy val publishSettings: Seq[Setting[_]] = Seq(
Test / publishArtifact := false,
pomIncludeRepository := (_ => false),
homepage := Some(url("https://github.com/typelevel/shapeless-3")),
licenses := Seq("Apache 2" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")),
scmInfo := Some(ScmInfo(url("https://github.com/typelevel/shapeless-3"), "scm:git:git@github.com:typelevel/shapeless-3.git")),
Comment on lines -194 to -204
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sbt-typelevel-ci-release sets this automatically.

developers := List(
Developer("milessabin", "Miles Sabin", "miles@milessabin.com", url("http://milessabin.com/blog")),
Developer("joroKr21", "Georgi Krastev", "joro.kr.21@gmail.com", url("https://twitter.com/Joro_Kr")),
Developer("TimWSpence", "Tim Spence", "timothywspence@gmail.com", url("https://twitter.com/timwspence"))
)
ThisBuild / licenses := Seq("Apache 2" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt"))
ThisBuild / developers := List(
Developer("milessabin", "Miles Sabin", "miles@milessabin.com", url("http://milessabin.com/blog")),
Developer("joroKr21", "Georgi Krastev", "joro.kr.21@gmail.com", url("https://twitter.com/Joro_Kr")),
Developer("TimWSpence", "Tim Spence", "timothywspence@gmail.com", url("https://twitter.com/timwspence"))
)

lazy val noPublishSettings =
publish / skip := true
6 changes: 2 additions & 4 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10")
addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.14.2")
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.0.1")
addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.4.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.3-RC2")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.1.0")