├── project ├── build.properties └── plugins.sbt ├── .gitignore ├── core └── shared │ └── src │ ├── main │ └── scala │ │ └── org │ │ └── scalacheck │ │ └── cats │ │ ├── implicits │ │ └── implicits.scala │ │ └── instances │ │ ├── CogenInstances.scala │ │ └── GenInstances.scala │ └── test │ └── scala │ └── org │ └── scalacheck │ └── cats │ ├── laws │ ├── CogenLaws.scala │ └── GenLaws.scala │ ├── ScalaCheckSetup.scala │ └── EqInstances.scala ├── .mergify.yml ├── .scalafmt.conf ├── CODE_OF_CONDUCT.md ├── LICENSE ├── site └── docs │ └── index.md ├── README.md └── .github └── workflows ├── clean.yml └── ci.yml /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.7.1 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | # vim 4 | *.sw? 5 | 6 | # Ignore [ce]tags files 7 | tags 8 | 9 | # VS Code 10 | .metals 11 | .bloop 12 | .vscode 13 | metals.sbt -------------------------------------------------------------------------------- /core/shared/src/main/scala/org/scalacheck/cats/implicits/implicits.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats 2 | 3 | import org.scalacheck.cats.instances._ 4 | 5 | package object implicits extends GenInstances with CogenInstances 6 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: automatically merge scala-steward's PRs 3 | conditions: 4 | - author=scala-steward 5 | - status-success=Travis CI - Pull Request 6 | actions: 7 | merge: 8 | method: squash 9 | label: 10 | add: [dependency-update] 11 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.3.1") 2 | addSbtPlugin("io.chrisdavenport" % "sbt-davenverse" % "0.1.4") 3 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1") 4 | addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.7") 5 | addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.2.0") 6 | -------------------------------------------------------------------------------- /core/shared/src/test/scala/org/scalacheck/cats/laws/CogenLaws.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats.laws 2 | 3 | import cats.laws.discipline._ 4 | import org.scalacheck.Cogen 5 | import org.scalacheck.cats.ScalaCheckSetup 6 | import org.scalacheck.cats.instances.CogenInstances._ 7 | 8 | class CogenLaws extends munit.DisciplineSuite with ScalaCheckSetup { 9 | checkAll("Cogen", ContravariantSemigroupalTests[Cogen].contravariant[Int, Int, Int]) 10 | checkAll("Cogen", MonoidKTests[Cogen].monoidK[Int]) 11 | } -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | # tune this file as appropriate to your style! see: https://olafurpg.github.io/scalafmt/#Configuration 2 | 3 | maxColumn = 100 4 | 5 | continuationIndent.callSite = 2 6 | 7 | newlines { 8 | sometimesBeforeColonInMethodReturnType = false 9 | } 10 | 11 | align { 12 | arrowEnumeratorGenerator = false 13 | ifWhileOpenParen = false 14 | openParenCallSite = false 15 | openParenDefnSite = false 16 | 17 | tokens = ["%", "%%"] 18 | } 19 | 20 | docstrings = JavaDoc 21 | 22 | rewrite { 23 | rules = [SortImports, RedundantBraces] 24 | redundantBraces.maxLines = 1 25 | } 26 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other such characteristics. 4 | 5 | Everyone is expected to follow the [Scala Code of Conduct] when dicussing the project on the available communication channels. If you are being harassed, please contact us immediately so that we can support you. 6 | 7 | ## Moderation 8 | 9 | Any questions, concerns, or moderation requests please contact a member of the project. 10 | 11 | - [Christopher Davenport](mailto:chris@christopherdavenport.tech) 12 | 13 | [Scala Code of Conduct]: https://www.scala-lang.org/conduct/ 14 | -------------------------------------------------------------------------------- /core/shared/src/main/scala/org/scalacheck/cats/instances/CogenInstances.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats.instances 2 | 3 | import cats._ 4 | import org.scalacheck._ 5 | 6 | object CogenInstances extends CogenInstances 7 | 8 | trait CogenInstances{ 9 | 10 | implicit val cogenContravariantSemigroupal: ContravariantSemigroupal[Cogen] = 11 | new ContravariantSemigroupal[Cogen]{ 12 | // Members declared in cats.Contravariant 13 | def contramap[A, B](fa: Cogen[A])(f: B => A): Cogen[B] = 14 | fa.contramap(f) 15 | 16 | // Members declared in cats.Semigroupal 17 | def product[A, B](fa: Cogen[A], fb: Cogen[B]): Cogen[(A, B)] = 18 | Cogen.tuple2(fa, fb) 19 | } 20 | 21 | implicit val cogenMonoidK: MonoidK[Cogen] = 22 | new MonoidK[Cogen] { 23 | def empty[A]: Cogen[A] = 24 | Cogen { (seed, _) => seed } 25 | def combineK[A](x: Cogen[A], y: Cogen[A]): Cogen[A] = 26 | Cogen { (seed, a) => y.perturb(x.perturb(seed, a), a) } 27 | } 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Christopher Davenport 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /core/shared/src/test/scala/org/scalacheck/cats/laws/GenLaws.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats.laws 2 | 3 | 4 | import cats.laws.discipline._ 5 | import cats.kernel.laws.discipline._ 6 | import cats.data.NonEmptyList 7 | import org.scalacheck.Gen 8 | import org.scalacheck.cats.ScalaCheckSetup 9 | import org.scalacheck.cats.instances.GenInstances._ 10 | 11 | class GenLaws extends munit.DisciplineSuite with ScalaCheckSetup { 12 | 13 | override def scalaCheckTestParameters = 14 | super.scalaCheckTestParameters.withMaxSize(20).withMinSuccessfulTests(20) 15 | 16 | // Tests Alternative 17 | checkAll("Gen", AlternativeTests[Gen].alternative[Int, Int, Int]) 18 | // Tests Monad 19 | checkAll("Gen", MonadTests[Gen].monad[Int, Int, Int]) 20 | // Tests FunctorFilter 21 | checkAll("Gen.FunctorFilterLaws", FunctorFilterTests[Gen].functorFilter[Int, Int, Int]) 22 | 23 | // Tests Monoid for Inner Given Monoid 24 | checkAll("Gen[String]", MonoidTests[Gen[String]].monoid) 25 | // Tests Low Priority Semigroup 26 | checkAll("Gen[NonEmptyList[Int]]", SemigroupTests[Gen[NonEmptyList[Int]]].semigroup) 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /core/shared/src/test/scala/org/scalacheck/cats/ScalaCheckSetup.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats 2 | 3 | import cats._ 4 | import cats.data._ 5 | import cats.syntax.all._ 6 | import org.scalacheck._ 7 | import org.scalacheck.cats.implicits._ 8 | import org.scalacheck.rng.Seed 9 | 10 | trait ScalaCheckSetup { 11 | 12 | implicit def genEq[A: Eq]: Eq[Gen[A]] = 13 | EqInstances.sampledGenEq(1000) 14 | 15 | implicit def cogenEq[A: Arbitrary]: Eq[Cogen[A]] = 16 | EqInstances.sampledCogenEq(1000) 17 | 18 | implicit lazy val arbitrarySeed: Arbitrary[Seed] = 19 | Arbitrary(Gen.choose(Long.MinValue, Long.MaxValue).map(n => Seed(n))) 20 | 21 | implicit lazy val cogenSeed: Cogen[Seed] = 22 | Cogen[Long].contramap(_.long._1) 23 | 24 | implicit def arbitraryNonEmptyList[A: Arbitrary]: Arbitrary[NonEmptyList[A]] = 25 | Arbitrary( 26 | (Arbitrary.arbitrary[A], Arbitrary.arbitrary[List[A]]).mapN(NonEmptyList(_, _)) 27 | ) 28 | 29 | // Better Arbitrary Gen 30 | implicit def arbitraryGen[A: Arbitrary]: Arbitrary[Gen[A]] = { 31 | val simple = Gen.const(Arbitrary.arbitrary[A]) 32 | val complex = Arbitrary.arbitrary[Seed => Seed].map { f => 33 | Gen.gen((params, seed) => Arbitrary.arbitrary[A].doApply(params, f(seed))) 34 | } 35 | Arbitrary(Gen.oneOf(simple, complex)) 36 | } 37 | 38 | implicit def arbitraryCogen[A: Cogen]: Arbitrary[Cogen[A]] = 39 | Arbitrary(Arbitrary.arbitrary[Seed => Seed].map { f => 40 | Cogen((seed, a) => f(Cogen[A].perturb(seed, a))) 41 | }) 42 | } -------------------------------------------------------------------------------- /site/docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | --- 5 | # cats-scalacheck [![Build Status](https://travis-ci.org/ChristopherDavenport/cats-scalacheck.svg?branch=master)](https://travis-ci.org/ChristopherDavenport/cats-scalacheck) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.chrisdavenport/cats-scalacheck_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.chrisdavenport/cats-scalacheck_2.12) 6 | 7 | ## Quick Start 8 | 9 | `cats-scalacheck` is published for scala 2.12 and 2.13, and scalajs 1.0.0. If you require scalajs 0.6 and/or scala 2.11, you may use the last version of this project: `0.2.0` 10 | 11 | To use cats-scalacheck in an existing SBT project, add the following dependency to your `build.sbt`: 12 | 13 | ```scala 14 | libraryDependencies += "io.chrisdavenport" %% "cats-scalacheck" % "" 15 | ``` 16 | 17 | For use with scalajs 1.0.x: 18 | 19 | ```scala 20 | libraryDependencies += "io.chrisdavenport" %%% "cats-scalacheck" % "" 21 | ``` 22 | 23 | ## Getting Started 24 | 25 | ```scala mdoc 26 | import org.scalacheck.{Gen, Arbitrary} 27 | import org.scalacheck.cats.implicits._ 28 | import cats.Applicative 29 | 30 | val apComposition: Gen[(Int, String)] = Applicative[Gen].product( 31 | Arbitrary.arbitrary[Int], 32 | Arbitrary.arbitrary[String] 33 | ) 34 | ``` 35 | 36 | ## Instances 37 | 38 | ### Gen 39 | 40 | - `Alternative[Gen]` 41 | - `Monad[Gen]` 42 | - `FunctorFilter[Gen]` 43 | - `Monoid[A] => Monoid[Gen[A]]` 44 | - `Semigroup[A] => Semigroup[Gen[A]]` 45 | 46 | ### Cogen 47 | 48 | - `ContravariantSemigroupal[Gen]` 49 | - `MonoidK[Gen]` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cats-scalacheck [![Build Status](https://travis-ci.org/ChristopherDavenport/cats-scalacheck.svg?branch=master)](https://travis-ci.org/ChristopherDavenport/cats-scalacheck) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.chrisdavenport/cats-scalacheck_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.chrisdavenport/cats-scalacheck_2.12) 2 | 3 | Inspiration Was Taken From the never published cats-check. Instances for Cats for scalacheck types. So all credit to [erik-stripe](https://github.com/erik-stripe) and the last maintainer [mdedetrich](https://github.com/mdedetrich) for their original work on this that helped me build this. 4 | 5 | ## Quick Start 6 | 7 | `cats-scalacheck` is published for scala 2.12 and 2.13, and scalajs 1.0.0. If you require scalajs 0.6 and/or scala 2.11, you may use the last version of this project: `0.2.0` 8 | 9 | To use cats-scalacheck in an existing SBT project, add the following dependency to your `build.sbt`: 10 | 11 | ```scala 12 | libraryDependencies += "io.chrisdavenport" %% "cats-scalacheck" % "" 13 | ``` 14 | 15 | For use with scalajs 1.0.x: 16 | 17 | ```scala 18 | libraryDependencies += "io.chrisdavenport" %%% "cats-scalacheck" % "" 19 | ``` 20 | 21 | 22 | ## Getting Started 23 | 24 | ```scala 25 | import org.scalacheck._ 26 | import org.scalacheck.cats.implicits._ 27 | import cats.Applicative 28 | import cats.implicits._ 29 | 30 | val apComposition: Gen[(Int, String)] = Applicative[Gen].product( 31 | Arbitrary.arbitrary[Int], 32 | Arbitrary.arbitrary[String] 33 | ) 34 | ``` 35 | 36 | ## Instances 37 | 38 | ### Gen 39 | 40 | - `Alternative[Gen]` 41 | - `Monad[Gen]` 42 | - `FunctorFilter[Gen]` 43 | - `Monoid[A] => Monoid[Gen[A]]` 44 | - `Semigroup[A] => Semigroup[Gen[A]]` 45 | 46 | ### Cogen 47 | 48 | - `ContravariantSemigroupal[Cogen]` 49 | - `MonoidK[Cogen]` 50 | 51 | ## Why in org.scalacheck 52 | 53 | This was necessary because scalacheck makes some of their instances package private that 54 | are required to roll these meaningfully. 55 | -------------------------------------------------------------------------------- /core/shared/src/main/scala/org/scalacheck/cats/instances/GenInstances.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats.instances 2 | 3 | import cats._ 4 | import cats.syntax.all._ 5 | import org.scalacheck.Gen 6 | 7 | object GenInstances extends GenInstances 8 | 9 | trait GenInstances extends GenInstances1 10 | 11 | sealed private[instances] trait GenInstances1 extends GenInstances0 { 12 | implicit val genInstances : Monad[Gen] with Alternative[Gen] with FunctorFilter[Gen] = new Monad[Gen] with Alternative[Gen] with FunctorFilter[Gen] { 13 | // Members declared in cats.Applicative 14 | override def pure[A](x: A): Gen[A] = 15 | Gen.const(x) 16 | 17 | // Members declared in cats.FlatMap 18 | override def flatMap[A, B](fa: Gen[A])(f: A => Gen[B]): Gen[B] = 19 | fa.flatMap(f) 20 | override def tailRecM[A, B](a: A)(f: A => Gen[Either[A,B]]): Gen[B] = 21 | Gen.tailRecM(a)(f) 22 | 23 | override def combineK[A](x: Gen[A], y: Gen[A]): Gen[A] = Gen.gen{ (params, seed) => 24 | val xGen = x.doApply(params, seed) 25 | if (xGen.retrieve.isDefined) xGen 26 | else y.doApply(params, seed) 27 | } 28 | 29 | override def empty[A]: Gen[A] = Gen.fail 30 | 31 | override def map2Eval[A, B, Z](fa: Gen[A], fb: Eval[Gen[B]])(f: (A, B) => Z): Eval[Gen[Z]] = 32 | Eval.later(map2(fa, Gen.lzy(fb.value))(f)) 33 | 34 | override def product[A, B](fa: Gen[A], fb: Gen[B]): Gen[(A, B)] = Gen.zip(fa, fb) 35 | 36 | override def functor: Functor[Gen] = this 37 | 38 | override def mapFilter[A, B](fa: Gen[A])(f: A => Option[B]): Gen[B] = 39 | fa.flatMap { a => 40 | f(a) match { 41 | case Some(b) => pure(b) 42 | case _ => Gen.fail 43 | } 44 | } 45 | } 46 | 47 | implicit def genMonoid[A: Monoid]: Monoid[Gen[A]] = new Monoid[Gen[A]]{ 48 | override def empty: Gen[A] = Gen.const(Monoid[A].empty) 49 | override def combine(x: Gen[A], y: Gen[A]) = for { 50 | xa <- x 51 | ya <- y 52 | } yield xa |+| ya 53 | } 54 | 55 | } 56 | 57 | sealed private[instances] trait GenInstances0 { 58 | implicit def genSemigroup[A: Semigroup]: Semigroup[Gen[A]] = new Semigroup[Gen[A]]{ 59 | override def combine(x: Gen[A], y: Gen[A]) = for { 60 | xa <- x 61 | ya <- y 62 | } yield xa |+| ya 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /core/shared/src/test/scala/org/scalacheck/cats/EqInstances.scala: -------------------------------------------------------------------------------- 1 | package org.scalacheck.cats 2 | 3 | import cats._ 4 | import org.scalacheck._ 5 | import rng.Seed 6 | import scala.util._ 7 | 8 | object EqInstances { 9 | def sampledCogenEq[A](trials: Int)(implicit ev: Arbitrary[A]): Eq[Cogen[A]] = { 10 | new Eq[Cogen[A]] { 11 | def eqv(x: Cogen[A], y: Cogen[A]): Boolean = { 12 | val gen : Gen[A] = ev.arbitrary 13 | val params : Gen.Parameters = Gen.Parameters.default 14 | // Loop Function which checks that the seeds from perturbing 15 | // given cogens create equivalent seeds for x iterations 16 | // to consider them equal 17 | def loop(count: Int, retries: Int, seed: Seed): Boolean = 18 | if (retries <= 0) sys.error("Generator Function Failed") 19 | else if (count <= 0) true // If make it through count all equal these are equal 20 | else { 21 | val rx = gen.doApply(params, seed) // Get Value 22 | rx.retrieve.fold( 23 | loop(count, retries - 1, rx.seed) // Loop As Necessary 24 | ){ a => 25 | val seed = Seed.random() 26 | val sx = x.perturb(seed, a) 27 | val sy = y.perturb(seed, a) 28 | if (sx != sy) false // If they are not equivalent 29 | else loop(count - 1, retries, rx.seed) // Another trial 30 | } 31 | } 32 | // Initiate Loop 33 | loop(trials, trials, Seed.random()) 34 | } 35 | } 36 | } 37 | 38 | def sampledGenEq[A: Eq](trials: Int): Eq[Gen[A]] = Eq.instance[Gen[A]]{ case (x, y) => 39 | val params = Gen.Parameters.default 40 | def loop(count: Int, seed: Seed): Boolean = { 41 | if (count <= 0) true 42 | else { 43 | // Leave this so the inequality creates the eq 44 | val tx = Try(x.doApply(params, seed)) 45 | val ty = Try(y.doApply(params, seed)) 46 | (tx, ty) match { 47 | case (Failure(_), Failure(_)) => 48 | // They both failed, good, keep going 49 | loop(count - 1, Seed.random()) 50 | case (Success(rx), Success(ry)) => 51 | if (Eq[Option[A]].neqv(rx.retrieve, ry.retrieve)) false 52 | else loop(count - 1, seed.next) 53 | case _ => 54 | false 55 | } 56 | } 57 | } 58 | loop(trials, Seed.random()) 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /.github/workflows/clean.yml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by sbt-github-actions using the 2 | # githubWorkflowGenerate task. You should add and commit this file to 3 | # your git repository. It goes without saying that you shouldn't edit 4 | # this file by hand! Instead, if you wish to make changes, you should 5 | # change your sbt build configuration to revise the workflow description 6 | # to meet your needs, then regenerate this file. 7 | 8 | name: Clean 9 | 10 | on: push 11 | 12 | jobs: 13 | delete-artifacts: 14 | name: Delete Artifacts 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - name: Delete artifacts 20 | run: | 21 | # Customize those three lines with your repository and credentials: 22 | REPO=${GITHUB_API_URL}/repos/${{ github.repository }} 23 | 24 | # A shortcut to call GitHub API. 25 | ghapi() { curl --silent --location --user _:$GITHUB_TOKEN "$@"; } 26 | 27 | # A temporary file which receives HTTP response headers. 28 | TMPFILE=/tmp/tmp.$$ 29 | 30 | # An associative array, key: artifact name, value: number of artifacts of that name. 31 | declare -A ARTCOUNT 32 | 33 | # Process all artifacts on this repository, loop on returned "pages". 34 | URL=$REPO/actions/artifacts 35 | while [[ -n "$URL" ]]; do 36 | 37 | # Get current page, get response headers in a temporary file. 38 | JSON=$(ghapi --dump-header $TMPFILE "$URL") 39 | 40 | # Get URL of next page. Will be empty if we are at the last page. 41 | URL=$(grep '^Link:' "$TMPFILE" | tr ',' '\n' | grep 'rel="next"' | head -1 | sed -e 's/.*.*//') 42 | rm -f $TMPFILE 43 | 44 | # Number of artifacts on this page: 45 | COUNT=$(( $(jq <<<$JSON -r '.artifacts | length') )) 46 | 47 | # Loop on all artifacts on this page. 48 | for ((i=0; $i < $COUNT; i++)); do 49 | 50 | # Get name of artifact and count instances of this name. 51 | name=$(jq <<<$JSON -r ".artifacts[$i].name?") 52 | ARTCOUNT[$name]=$(( $(( ${ARTCOUNT[$name]} )) + 1)) 53 | 54 | id=$(jq <<<$JSON -r ".artifacts[$i].id?") 55 | size=$(( $(jq <<<$JSON -r ".artifacts[$i].size_in_bytes?") )) 56 | printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size 57 | ghapi -X DELETE $REPO/actions/artifacts/$id 58 | done 59 | done -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by sbt-github-actions using the 2 | # githubWorkflowGenerate task. You should add and commit this file to 3 | # your git repository. It goes without saying that you shouldn't edit 4 | # this file by hand! Instead, if you wish to make changes, you should 5 | # change your sbt build configuration to revise the workflow description 6 | # to meet your needs, then regenerate this file. 7 | 8 | name: Continuous Integration 9 | 10 | on: 11 | pull_request: 12 | branches: ['**'] 13 | push: 14 | branches: ['**'] 15 | tags: [v*] 16 | 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | 20 | jobs: 21 | build: 22 | name: Build and Test 23 | strategy: 24 | matrix: 25 | os: [ubuntu-latest] 26 | scala: [2.12.16, 2.13.8, 3.1.3] 27 | java: [adopt@1.8, adopt@1.11] 28 | runs-on: ${{ matrix.os }} 29 | steps: 30 | - name: Checkout current branch (full) 31 | uses: actions/checkout@v2 32 | with: 33 | fetch-depth: 0 34 | 35 | - name: Setup Java and Scala 36 | uses: olafurpg/setup-scala@v12 37 | with: 38 | java-version: ${{ matrix.java }} 39 | 40 | - name: Cache sbt 41 | uses: actions/cache@v2 42 | with: 43 | path: | 44 | ~/.sbt 45 | ~/.ivy2/cache 46 | ~/.coursier/cache/v1 47 | ~/.cache/coursier/v1 48 | ~/AppData/Local/Coursier/Cache/v1 49 | ~/Library/Caches/Coursier/v1 50 | key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} 51 | 52 | - name: Setup Ruby 53 | if: matrix.scala == '2.13.8' 54 | uses: ruby/setup-ruby@v1 55 | with: 56 | ruby-version: 3.0.1 57 | 58 | - name: Install microsite dependencies 59 | if: matrix.scala == '2.13.8' 60 | run: | 61 | gem install saas 62 | gem install jekyll -v 4.2.0 63 | 64 | - name: Check that workflows are up to date 65 | run: sbt --client '++${{ matrix.scala }}; githubWorkflowCheck' 66 | 67 | - run: sbt --client '++${{ matrix.scala }}; test; mimaReportBinaryIssues' 68 | 69 | - if: matrix.scala == '2.13.8' 70 | run: sbt --client '++${{ matrix.scala }}; site/makeMicrosite' 71 | 72 | publish: 73 | name: Publish Artifacts 74 | needs: [build] 75 | if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') 76 | strategy: 77 | matrix: 78 | os: [ubuntu-latest] 79 | scala: [3.1.3] 80 | java: [adopt@1.8] 81 | runs-on: ${{ matrix.os }} 82 | steps: 83 | - name: Checkout current branch (full) 84 | uses: actions/checkout@v2 85 | with: 86 | fetch-depth: 0 87 | 88 | - name: Setup Java and Scala 89 | uses: olafurpg/setup-scala@v12 90 | with: 91 | java-version: ${{ matrix.java }} 92 | 93 | - name: Cache sbt 94 | uses: actions/cache@v2 95 | with: 96 | path: | 97 | ~/.sbt 98 | ~/.ivy2/cache 99 | ~/.coursier/cache/v1 100 | ~/.cache/coursier/v1 101 | ~/AppData/Local/Coursier/Cache/v1 102 | ~/Library/Caches/Coursier/v1 103 | key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} 104 | 105 | - uses: olafurpg/setup-gpg@v3 106 | 107 | - name: Setup Ruby 108 | uses: ruby/setup-ruby@v1 109 | with: 110 | ruby-version: 3.0.1 111 | 112 | - name: Install microsite dependencies 113 | run: | 114 | gem install saas 115 | gem install jekyll -v 4.2.0 116 | 117 | - name: Publish artifacts to Sonatype 118 | env: 119 | PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} 120 | PGP_SECRET: ${{ secrets.PGP_SECRET }} 121 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} 122 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} 123 | run: sbt --client '++${{ matrix.scala }}; ci-release' 124 | 125 | - uses: christopherdavenport/create-ghpages-ifnotexists@v1 126 | 127 | - name: Publish microsite 128 | run: sbt --client '++${{ matrix.scala }}; site/publishMicrosite' --------------------------------------------------------------------------------