From 5459e943bc4e4f16f109df95c4c66bdd7acae6a2 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 4 Mar 2022 23:59:15 +0000 Subject: [PATCH 1/5] Migrate to sbt-typelevel --- .github/workflows/ci.yml | 245 ++++++++++++++++++++++++++++++++++ .github/workflows/clean.yml | 59 ++++++++ .github/workflows/release.yml | 32 ----- .github/workflows/scala.yml | 18 --- build.sbt | 27 ++-- project/Build.scala | 3 +- project/plugins.sbt | 2 +- 7 files changed, 318 insertions(+), 68 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/clean.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/scala.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..18303c80 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,245 @@ +# This file was automatically generated by sbt-github-actions using the +# githubWorkflowGenerate task. You should add and commit this file to +# your git repository. It goes without saying that you shouldn't edit +# this file by hand! Instead, if you wish to make changes, you should +# change your sbt build configuration to revise the workflow description +# to meet your needs, then regenerate this file. + +name: Continuous Integration + +on: + pull_request: + branches: ['**'] + push: + branches: ['**'] + tags: [v*] + +env: + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_CREDENTIAL_HOST: ${{ secrets.SONATYPE_CREDENTIAL_HOST }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + PGP_SECRET: ${{ secrets.PGP_SECRET }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + build: + name: Build and Test + strategy: + matrix: + os: [ubuntu-latest] + scala: [2.12.15, 2.13.6, 3.1.1] + java: [temurin@8] + project: [rootJS, rootJVM, rootNative] + exclude: + - project: rootNative + scala: 3.1.1 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Download Java (temurin@8) + id: download-java-temurin-8 + if: matrix.java == 'temurin@8' + uses: typelevel/download-java@v1 + with: + distribution: temurin + java-version: 8 + + - name: Setup Java (temurin@8) + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v2 + with: + distribution: jdkfile + java-version: 8 + jdkFile: ${{ steps.download-java-temurin-8.outputs.jdkFile }} + + - name: Cache sbt + uses: actions/cache@v2 + with: + path: | + ~/.sbt + ~/.ivy2/cache + ~/.coursier/cache/v1 + ~/.cache/coursier/v1 + ~/AppData/Local/Coursier/Cache/v1 + ~/Library/Caches/Coursier/v1 + key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + + - name: Check that workflows are up to date + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' 'project /' githubWorkflowCheck + + - name: scalaJSLink + if: matrix.project == 'rootJS' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/scalaJSLinkerResult + + - name: nativeLink + if: matrix.project == 'rootNative' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/nativeLink + + - name: Test + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' test + + - name: Check binary compatibility + if: matrix.java == 'temurin@8' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' mimaReportBinaryIssues + + - name: Generate API documentation + if: matrix.java == 'temurin@8' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' doc + + - name: Make target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') + run: mkdir -p native/target target .js/target squants-docs/target .jvm/target .native/target jvm/target js/target project/target + + - name: Compress target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') + run: tar cf targets.tar native/target target .js/target squants-docs/target .jvm/target .native/target jvm/target js/target project/target + + - name: Upload target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') + uses: actions/upload-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-${{ matrix.scala }}-${{ matrix.project }} + path: targets.tar + + publish: + name: Publish Artifacts + needs: [build] + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/master') + strategy: + matrix: + os: [ubuntu-latest] + scala: [3.1.1] + java: [temurin@8] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Download Java (temurin@8) + id: download-java-temurin-8 + if: matrix.java == 'temurin@8' + uses: typelevel/download-java@v1 + with: + distribution: temurin + java-version: 8 + + - name: Setup Java (temurin@8) + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v2 + with: + distribution: jdkfile + java-version: 8 + jdkFile: ${{ steps.download-java-temurin-8.outputs.jdkFile }} + + - name: Cache sbt + uses: actions/cache@v2 + with: + path: | + ~/.sbt + ~/.ivy2/cache + ~/.coursier/cache/v1 + ~/.cache/coursier/v1 + ~/AppData/Local/Coursier/Cache/v1 + ~/Library/Caches/Coursier/v1 + key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + + - name: Download target directories (2.12.15, rootJS) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.15-rootJS + + - name: Inflate target directories (2.12.15, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.12.15, rootJVM) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.15-rootJVM + + - name: Inflate target directories (2.12.15, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.12.15, rootNative) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.15-rootNative + + - name: Inflate target directories (2.12.15, rootNative) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13.6, rootJS) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.6-rootJS + + - name: Inflate target directories (2.13.6, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13.6, rootJVM) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.6-rootJVM + + - name: Inflate target directories (2.13.6, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13.6, rootNative) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.6-rootNative + + - name: Inflate target directories (2.13.6, rootNative) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (3.1.1, rootJS) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.1-rootJS + + - name: Inflate target directories (3.1.1, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (3.1.1, rootJVM) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.1-rootJVM + + - name: Inflate target directories (3.1.1, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Import signing key + if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == '' + run: echo $PGP_SECRET | base64 -di | gpg --import + + - name: Import signing key and strip passphrase + if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != '' + run: | + echo "$PGP_SECRET" | base64 -di > /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) + + - name: Publish + run: sbt '++${{ matrix.scala }}' tlRelease diff --git a/.github/workflows/clean.yml b/.github/workflows/clean.yml new file mode 100644 index 00000000..547aaa43 --- /dev/null +++ b/.github/workflows/clean.yml @@ -0,0 +1,59 @@ +# This file was automatically generated by sbt-github-actions using the +# githubWorkflowGenerate task. You should add and commit this file to +# your git repository. It goes without saying that you shouldn't edit +# this file by hand! Instead, if you wish to make changes, you should +# change your sbt build configuration to revise the workflow description +# to meet your needs, then regenerate this file. + +name: Clean + +on: push + +jobs: + delete-artifacts: + name: Delete Artifacts + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Delete artifacts + run: | + # Customize those three lines with your repository and credentials: + REPO=${GITHUB_API_URL}/repos/${{ github.repository }} + + # A shortcut to call GitHub API. + ghapi() { curl --silent --location --user _:$GITHUB_TOKEN "$@"; } + + # A temporary file which receives HTTP response headers. + TMPFILE=/tmp/tmp.$$ + + # An associative array, key: artifact name, value: number of artifacts of that name. + declare -A ARTCOUNT + + # Process all artifacts on this repository, loop on returned "pages". + URL=$REPO/actions/artifacts + while [[ -n "$URL" ]]; do + + # Get current page, get response headers in a temporary file. + JSON=$(ghapi --dump-header $TMPFILE "$URL") + + # Get URL of next page. Will be empty if we are at the last page. + URL=$(grep '^Link:' "$TMPFILE" | tr ',' '\n' | grep 'rel="next"' | head -1 | sed -e 's/.*.*//') + rm -f $TMPFILE + + # Number of artifacts on this page: + COUNT=$(( $(jq <<<$JSON -r '.artifacts | length') )) + + # Loop on all artifacts on this page. + for ((i=0; $i < $COUNT; i++)); do + + # Get name of artifact and count instances of this name. + name=$(jq <<<$JSON -r ".artifacts[$i].name?") + ARTCOUNT[$name]=$(( $(( ${ARTCOUNT[$name]} )) + 1)) + + id=$(jq <<<$JSON -r ".artifacts[$i].id?") + size=$(( $(jq <<<$JSON -r ".artifacts[$i].size_in_bytes?") )) + printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size + ghapi -X DELETE $REPO/actions/artifacts/$id + done + done diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 9b5232cf..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Release -on: - push: - branches: [master] - tags: ["*"] -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: olafurpg/setup-scala@v10 - - uses: olafurpg/setup-gpg@v3 - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ~/.cache/coursier/v1 - key: ${{ runner.os }}-coursier-${{ hashFiles('build.sbt') }}-${{ hashFiles('project/*.scala') }} - restore-keys: ${{ runner.os }}-coursier- - - name: Cache .sbt - uses: actions/cache@v1 - with: - path: ~/.sbt - key: ${{ runner.os }}-sbt-${{ hashFiles('build.sbt') }}-${{ hashFiles('project/*.scala') }} - restore-keys: ${{ runner.os }}-sbt- - - name: Publish - run: sbt clean ci-release - env: - PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} - PGP_SECRET: ${{ secrets.PGP_SECRET }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml deleted file mode 100644 index 4f99665c..00000000 --- a/.github/workflows/scala.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: build - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - uses: coursier/cache-action@v3 - - name: Set up JDK 1.8 - uses: olafurpg/setup-scala@v12 - with: - java-version: 1.8 - - name: Run tests - run: | - sbt +squantsJVM/test +squantsJS/test +squantsNative/compile diff --git a/build.sbt b/build.sbt index e3ca7f42..ddb5d3fe 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,3 @@ -import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType} - lazy val defaultSettings = Project.defaultSettings ++ Compiler.defaultSettings ++ @@ -14,9 +12,11 @@ Global / onChangedBuildSource := ReloadOnSourceChanges ThisBuild / turbo := true inThisBuild(List( + tlBaseVersion := "1.8", organization := "org.typelevel", homepage := Some(url("http://www.squants.com/")), licenses := Seq("Apache 2.0" -> url("http://www.opensource.org/licenses/Apache-2.0")), + tlCiReleaseBranches := Seq("master"), developers := List( Developer( "garyKeorkunian", @@ -24,7 +24,11 @@ inThisBuild(List( "unknown", url("http://www.linkedin.com/in/garykeorkunian") ) - ) + ), + crossScalaVersions := Versions.ScalaCross, + githubWorkflowBuildMatrixExclusions += + MatrixExclude(Map("project" -> "rootNative", "scala" -> Versions.Scala3)), + tlVersionIntroduced := Map("3" -> "1.8.3") )) lazy val squants = @@ -43,10 +47,12 @@ lazy val squants = .jsSettings( Test / parallelExecution := false, Test / excludeFilter := "*Serializer.scala" || "*SerializerSpec.scala", + tlVersionIntroduced ++= List("2.12", "2.13").map(_ -> "1.6.0").toMap, ) .nativeSettings( crossScalaVersions := Versions.ScalaCross.filterNot(_.startsWith("3")), Compile / doc / sources := List(), // Can't build docs in native + tlVersionIntroduced := List("2.12", "2.13").map(_ -> "1.7.2").toMap, ) lazy val docs = @@ -59,17 +65,6 @@ lazy val docs = mdocAutoDependency := false, ) -lazy val root = project.in(file(".")) +lazy val root = tlCrossRootProject + .aggregate(squants) .settings(defaultSettings: _*) - .settings(noPublishSettings) - .settings( - name := "squants", - ) - .aggregate(squants.jvm, squants.js, squants.native) - -lazy val noPublishSettings = Seq( - publish := {}, - publishLocal := {}, - publishArtifact := false, - publish / skip := true -) diff --git a/project/Build.scala b/project/Build.scala index b13ef3f7..e82edcc1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -7,7 +7,8 @@ import com.typesafe.sbt.osgi.SbtOsgi import com.typesafe.sbt.osgi.SbtOsgi.autoImport._ object Versions { - val Scala = "3.1.1" + val Scala3 = "3.1.1" + val Scala = Scala3 val ScalaCross = Seq("2.12.15", "2.13.6", Scala) diff --git a/project/plugins.sbt b/project/plugins.sbt index 3e052bff..e5e7396b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -9,4 +9,4 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.1") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10") +addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.4.6") From 50498c6c23c543465d78b1aadca255b8b1e2f505 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sat, 5 Mar 2022 00:10:17 +0000 Subject: [PATCH 2/5] Mima configuring --- build.sbt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index ddb5d3fe..f67bc34a 100644 --- a/build.sbt +++ b/build.sbt @@ -28,7 +28,8 @@ inThisBuild(List( crossScalaVersions := Versions.ScalaCross, githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("project" -> "rootNative", "scala" -> Versions.Scala3)), - tlVersionIntroduced := Map("3" -> "1.8.3") + tlVersionIntroduced := Map("2.13" -> "1.6.0", "3" -> "1.8.3"), + tlMimaPreviousVersions ~= { _.filterNot(Set("1.7.1", "1.7.2", "1.7.3")) } // unpublished tags (?) )) lazy val squants = @@ -52,7 +53,7 @@ lazy val squants = .nativeSettings( crossScalaVersions := Versions.ScalaCross.filterNot(_.startsWith("3")), Compile / doc / sources := List(), // Can't build docs in native - tlVersionIntroduced := List("2.12", "2.13").map(_ -> "1.7.2").toMap, + tlVersionIntroduced := List("2.12", "2.13").map(_ -> "1.8.0").toMap, ) lazy val docs = From 30cabc453fefdc9e90209b2f8facd4c7039dfc88 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 6 Mar 2022 13:07:23 +0000 Subject: [PATCH 3/5] Bump base ver to 2.0, build tweaks --- build.sbt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index f67bc34a..cdaa7c7a 100644 --- a/build.sbt +++ b/build.sbt @@ -12,7 +12,7 @@ Global / onChangedBuildSource := ReloadOnSourceChanges ThisBuild / turbo := true inThisBuild(List( - tlBaseVersion := "1.8", + tlBaseVersion := "2.0", organization := "org.typelevel", homepage := Some(url("http://www.squants.com/")), licenses := Seq("Apache 2.0" -> url("http://www.opensource.org/licenses/Apache-2.0")), @@ -28,8 +28,6 @@ inThisBuild(List( crossScalaVersions := Versions.ScalaCross, githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("project" -> "rootNative", "scala" -> Versions.Scala3)), - tlVersionIntroduced := Map("2.13" -> "1.6.0", "3" -> "1.8.3"), - tlMimaPreviousVersions ~= { _.filterNot(Set("1.7.1", "1.7.2", "1.7.3")) } // unpublished tags (?) )) lazy val squants = @@ -48,20 +46,18 @@ lazy val squants = .jsSettings( Test / parallelExecution := false, Test / excludeFilter := "*Serializer.scala" || "*SerializerSpec.scala", - tlVersionIntroduced ++= List("2.12", "2.13").map(_ -> "1.6.0").toMap, ) .nativeSettings( crossScalaVersions := Versions.ScalaCross.filterNot(_.startsWith("3")), Compile / doc / sources := List(), // Can't build docs in native - tlVersionIntroduced := List("2.12", "2.13").map(_ -> "1.8.0").toMap, ) lazy val docs = project.in(file("squants-docs")) .dependsOn(squants.jvm) - .enablePlugins(MdocPlugin) + .enablePlugins(MdocPlugin, NoPublishPlugin) .settings( - scalaVersion := "2.13.7", + scalaVersion := Versions.Scala, mdocOut := (ThisBuild / baseDirectory).value, mdocAutoDependency := false, ) From bcdc0aa1ccee2194a0f8d3b6de21cc29106270a5 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 6 Mar 2022 13:14:36 +0000 Subject: [PATCH 4/5] Poke ci From 51595bf5cf1e94262cc68da36fe2dc0c5d92238c Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 6 Mar 2022 13:39:34 +0000 Subject: [PATCH 5/5] Fix broken test --- shared/src/test/scala/squants/space/VolumeSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/test/scala/squants/space/VolumeSpec.scala b/shared/src/test/scala/squants/space/VolumeSpec.scala index 3cb9ca71..b3622bf8 100644 --- a/shared/src/test/scala/squants/space/VolumeSpec.scala +++ b/shared/src/test/scala/squants/space/VolumeSpec.scala @@ -167,7 +167,7 @@ class VolumeSpec extends AnyFlatSpec with Matchers { } it should "return Length when cube rooted" in { - CubicMeters(27).cubeRoot should be(Meters(3)) + CubicMeters(64).cubeRoot should be(Meters(4)) } behavior of "VolumeConversions"