From a20a6494092ddb4b1b3e1fc1741e0eb72e87e018 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 30 Sep 2026 16:32:07 +0200 Subject: [PATCH 1/4] build(deps): update toolchain and audited dependencies - sbt 1.12.13 -> 1.13.0 (security fix for GHSA-943m-f264-54p4; verified boot with the full plugin set under the official launcher) - jsoniter-scala 2.38.17 -> 2.41.2 - kyo-prelude / kyo-schema 1.0.0-RC6 -> 1.0.0-RC7 - scalacheck 1.19.0 -> 1.20.0; vulcan 1.13.0 -> 1.14.0 - zio 2.1.24 -> 2.1.26; zio-prelude 1.0.0-RC41 -> 1.0.0-RC48 - sbt-scalafmt 2.5.6 -> 2.6.2; sbt-scalafix 0.14.7 -> 0.14.9 - sbt-stryker4s 0.20.3 -> 0.20.4 (multi-module invocation fix) - sbt-typelevel-ci-release/-settings/-site 0.8.6 -> 0.8.7 - typelevel-scalafix 0.5.0 -> 0.6.0 --- build.sbt | 16 ++++++++-------- project/build.properties | 2 +- project/plugins.sbt | 13 +++++++------ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/build.sbt b/build.sbt index f3c8e3c7..c071826f 100644 --- a/build.sbt +++ b/build.sbt @@ -95,7 +95,7 @@ ThisBuild / githubWorkflowBuildPreamble ++= Seq( ThisBuild / semanticdbEnabled := true ThisBuild / semanticdbVersion := scalafixSemanticdb.revision ThisBuild / scalafixDependencies += - "org.typelevel" %% "typelevel-scalafix" % "0.5.0" + "org.typelevel" %% "typelevel-scalafix" % "0.6.0" ThisBuild / scalacOptions += "-Wunused:all" // Raise kindlings' per-derivation macro-expansion budget from its 5s default (which a loaded // machine intermittently trips: `derived timed out after 5000ms`) to 30s. One namespace per @@ -352,7 +352,7 @@ lazy val cats = Typelevel %% "cats-core" % "2.13.0" lazy val catsLaws = Typelevel %% "cats-laws" % "2.13.0" lazy val disciplineCore = Typelevel %% "discipline-core" % "1.7.0" lazy val discipline = Typelevel %% "discipline-specs2" % "2.0.0" -lazy val scalacheck = ScalaCheckOrg %% "scalacheck" % "1.19.0" +lazy val scalacheck = ScalaCheckOrg %% "scalacheck" % "1.20.0" lazy val monocle = Optics %% "monocle-core" % "3.3.0" // droste — the recursion-scheme baseline for the schemes benchmarks (pattern // functor + Fix encoding). Benchmark-only; never a published dependency. @@ -388,7 +388,7 @@ lazy val circe = Circe %% "circe-core" % "0.14.16" // vulcan pins apache-avro 1.11.x transitively; our explicit avro 1.12.2 pin // below wins on the compile classpath, and as an Optional dep vulcan forces // nothing downstream anyway. -lazy val vulcan = "com.github.fd4s" %% "vulcan" % "1.13.0" +lazy val vulcan = "com.github.fd4s" %% "vulcan" % "1.14.0" lazy val circeParser = Circe %% "circe-parser" % "0.14.16" // Pin apache-avro 1.12.2 explicitly even though kindlings-avro-derivation // brings it transitively — keeps the reachable runtime jar visible in @@ -443,7 +443,7 @@ lazy val avro = ApacheAvro % "avro" % "1.12.2" // zio — runtime + ZEnvironment/ZLayer/Ref, the DI surface `cats-eo-zio` // integrates with. Compile-scope there: the module's whole API names // ZIO types. -lazy val zioCore = Ziverge %% "zio" % "2.1.24" +lazy val zioCore = Ziverge %% "zio" % "2.1.26" // zio-schema / zio-json / zio-prelude — Optional in `cats-eo-zio`: only // the `eo.zio.schema` / `eo.zio.json` / `eo.zio.prelude` sub-packages name // their types, callers who want a seam add its artifact themselves (the @@ -456,7 +456,7 @@ lazy val zioSchema = Ziverge %% "zio-schema" % ZioSchemaVersion lazy val zioSchemaDerivation = Ziverge %% "zio-schema-derivation" % ZioSchemaVersion lazy val zioSchemaJson = Ziverge %% "zio-schema-json" % ZioSchemaVersion lazy val zioJson = Ziverge %% "zio-json" % "0.7.44" -lazy val zioPrelude = Ziverge %% "zio-prelude" % "1.0.0-RC41" +lazy val zioPrelude = Ziverge %% "zio-prelude" % "1.0.0-RC48" // kyo-prelude — Kyo's dependency-light pure layer: Env / Var / Layer / // TypeMap all live here (kyo-data + kyo-kernel come transitively; no // kyo-core IO runtime). `cats-eo-kyo` deliberately depends on nothing @@ -465,7 +465,7 @@ lazy val zioPrelude = Ziverge %% "zio-prelude" % "1.0.0-RC41" // kyo's macro classes can only LOAD in a JDK 25+ compiler JVM. The kyo // module therefore builds on a 25 toolchain (`tlJdkRelease := 25` there) // and drops out of the root aggregate on older JVMs — see `kyoBuildActive`. -val KyoVersion = "1.0.0-RC6" +val KyoVersion = "1.0.0-RC7" lazy val kyoPrelude = GetKyo %% "kyo-prelude" % KyoVersion // kyo-schema — schema-driven codecs/foci (kyo-data only; no kyo-core). // Optional in `cats-eo-kyo`: only the `eo.kyo.schema` sub-package names @@ -485,8 +485,8 @@ val kyoBuildActive: Boolean = .get("java.specification.version") .exists(v => scala.util.Try(v.toInt).getOrElse(0) >= 25) -lazy val jsoniterCore = Plokhotnyuk %% "jsoniter-scala-core" % "2.38.17" -lazy val jsoniterMacros = Plokhotnyuk %% "jsoniter-scala-macros" % "2.38.17" +lazy val jsoniterCore = Plokhotnyuk %% "jsoniter-scala-core" % "2.41.2" +lazy val jsoniterMacros = Plokhotnyuk %% "jsoniter-scala-macros" % "2.41.2" lazy val commonSettings = Seq( // `version` is NOT set here — sbt-typelevel-ci-release derives it diff --git a/project/build.properties b/project/build.properties index 7c95fc19..e0a1aa02 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.12.13 +sbt.version=1.13.0 diff --git a/project/plugins.sbt b/project/plugins.sbt index bae375b7..ae078589 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -15,12 +15,13 @@ addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.8") // test deps), so every mutant comes back NoCoverage; switching the // current project first makes specs2 visible. 0.20.x auto-derives the // Scala 3 dialect from scalaVersion. -addSbtPlugin("io.stryker-mutator" % "sbt-stryker4s" % "0.20.3") +// 0.20.4 fixed multi-module invocation; the `project ; stryker` workaround still works. +addSbtPlugin("io.stryker-mutator" % "sbt-stryker4s" % "0.20.4") // Format check gate for CI (`sbt scalafmtCheckAll scalafmtSbtCheck` // in the workflow). The project ships a `.scalafmt.conf` pinned to // 3.x; sbt-scalafmt honours that pin automatically. -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.6") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.6.2") // `sbt-typelevel-ci-release` wires the Sonatype Central Portal flow // (post-June-2025 OSSRH sunset): derives the version from git tags, @@ -29,7 +30,7 @@ addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.6") // `sbt-typelevel-mima` dependency so binary-compat checks run on // every CI build from 0.1.1 onward (0.1.0 has no previous version // to compare against; see `mima.sbt`). -addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.8.6") +addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.8.7") // `sbt-typelevel-settings` contributes the curated scalac flag set // (`-deprecation -feature -unchecked -Wunused:... -Wvalue-discard`, @@ -37,7 +38,7 @@ addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.8.6") // in CI via `tlFatalWarnings`. Not transitively brought in by // `-ci-release`, so we add it explicitly — without it each module is // responsible for its own scalacOptions. -addSbtPlugin("org.typelevel" % "sbt-typelevel-settings" % "0.8.6") +addSbtPlugin("org.typelevel" % "sbt-typelevel-settings" % "0.8.7") // `sbt-scalafix` wires Scalafix into the build (`sbt scalafixAll`, // `sbt scalafixAll --check`). Pinned to the same minor as the @@ -50,13 +51,13 @@ addSbtPlugin("org.typelevel" % "sbt-typelevel-settings" % "0.8.6") // trailing comma. scalafix fully owns imports (sorting, grouping, and now // trailing commas), so scalafmt is set to `trailingCommas = keep` // (.scalafmt.conf) to stay out of import formatting — the two no longer fight. -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.14.7") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.14.9") // `sbt-typelevel-site` drives the Laika-based docs site. Pairs the // mdoc-compiled markdown under `site/docs/` with the Helium theme // configured from build.sbt. Pinned to the same 0.8.5 family as // ci-release so they share plugin transitive versions. -addSbtPlugin("org.typelevel" % "sbt-typelevel-site" % "0.8.6") +addSbtPlugin("org.typelevel" % "sbt-typelevel-site" % "0.8.7") // `unused-code-plugin` from xuwei-k contributes the `WarnUnusedCode` / // `ErrorUnusedCode` / `RemoveUnusedCode` Scalafix `SyntacticRule`s, From 04a219ff66880cdf222a28937e9bfc2f8bf78e01 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 30 Sep 2026 16:32:11 +0200 Subject: [PATCH 2/4] chore(deps): replace Scala Steward with Dependabot's native sbt ecosystem Dependabot has supported the sbt package ecosystem since May 2026, and unlike Steward's GITHUB_TOKEN-opened PRs it runs the repo's CI on every update PR. Add the sbt ecosystem to dependabot.yml, retire the Steward workflow and its config (the jackson updates.ignore entries were inert, as jackson only arrives transitively via avro), drop the now-dangling validate-steward job from ci.yml, and point the release-note bot-author exclusion at dependabot[bot]. --- .github/dependabot.yml | 15 ++++++++++++--- .github/release.yml | 4 +++- .github/workflows/ci.yml | 30 +++++------------------------ .github/workflows/scala-steward.yml | 27 -------------------------- .scala-steward.conf | 19 ------------------ 5 files changed, 20 insertions(+), 75 deletions(-) delete mode 100644 .github/workflows/scala-steward.yml delete mode 100644 .scala-steward.conf diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 61644ccc..a487b876 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,8 +1,10 @@ version: 2 updates: - # Keep GitHub Actions pinned versions current. Scala / sbt-plugin - # updates are tracked by Scala Steward (.github/workflows/scala-steward.yml); - # Dependabot doesn't natively understand sbt. + # Keep GitHub Actions pinned versions current (github-actions ecosystem) and + # sbt library / plugin / Scala version upgrades (sbt ecosystem). Dependabot + # has natively supported the `sbt` package ecosystem since May 2026 + # (github.blog changelog 2026-05-26) — before that, sbt updates were Scala + # Steward's job, which is why Steward is retired in favor of Dependabot. - package-ecosystem: "github-actions" directory: "/" schedule: @@ -10,3 +12,10 @@ updates: labels: - "dependencies" - "github-actions" + - package-ecosystem: "sbt" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + - "sbt" diff --git a/.github/release.yml b/.github/release.yml index 99945202..e80c5c1d 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -3,7 +3,9 @@ changelog: exclude: authors: - - scala-steward + # Scala Steward is retired (dependabot.yml now covers sbt); keep bot + # PRs out of the auto-generated release notes. + - dependabot[bot] categories: - title: "⚠️ Breaking changes" labels: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6978522b..ffb30214 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -366,31 +366,11 @@ jobs: modules-ignore: cats-eo-docs_3 configs-ignore: test scala-tool scala-doc-tool test-internal - validate-steward: - name: Validate Steward Config - strategy: - matrix: - os: [ubuntu-22.04] - java: [temurin@17] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout current branch (fast) - uses: actions/checkout@v7 - - - name: Setup Java (temurin@17) - id: setup-java-temurin-17 - if: matrix.java == 'temurin@17' - uses: actions/setup-java@v6 - with: - distribution: temurin - java-version: 17 - - - uses: coursier/setup-action@v3 - with: - apps: scala-steward - - - run: scala-steward validate-repo-config .scala-steward.conf - + # NOTE: the sbt-github-actions-generated `validate-steward` job was removed + # here by hand as part of the Scala Steward → Dependabot migration (Dependabot + # now covers sbt). It will be dropped again by the next `sbt + # githubWorkflowGenerate`: sbt-typelevel only emits the job when + # .scala-steward.conf exists, and that file is gone. site: name: Generate Site strategy: diff --git a/.github/workflows/scala-steward.yml b/.github/workflows/scala-steward.yml deleted file mode 100644 index f4f1f158..00000000 --- a/.github/workflows/scala-steward.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Scala Steward — opens PRs for sbt library / plugin / Scala version upgrades. -# Dependabot (see .github/dependabot.yml) doesn't understand sbt, so it only -# covers GitHub Actions; Steward covers everything under build.sbt / project/. -# -# Uses the default GITHUB_TOKEN (the repo already grants Actions write + -# create-PR permission). ponytail: GITHUB_TOKEN-opened PRs do NOT trigger the -# CI workflow — add a PAT as the SCALA_STEWARD_TOKEN secret and swap it into -# `github-token` below if you want CI to run on Steward PRs automatically. -name: Scala Steward - -on: - schedule: - - cron: "0 6 * * 1" # Mondays 06:00 UTC - workflow_dispatch: # allow manual runs from the Actions tab - -permissions: - contents: write - pull-requests: write - -jobs: - scala-steward: - name: Launch Scala Steward - runs-on: ubuntu-22.04 - steps: - - uses: scala-steward-org/scala-steward-action@v2.96.0 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.scala-steward.conf b/.scala-steward.conf deleted file mode 100644 index 47edb678..00000000 --- a/.scala-steward.conf +++ /dev/null @@ -1,19 +0,0 @@ -# jackson 2.22.0 regressed the @JsonIgnoreProperties case-insensitive fix -# (CVE-2026-54515, dependabot alert #7). 2.22.1 carries the re-fix and is what -# apache-avro 1.12.2's parent BOM resolves, so the build is already past it. -# -# There is deliberately NO `updates.pin` here. A pin like `version = "2.22."` -# is a SERIES LOCK, not a floor: it would block Steward from ever proposing -# 2.23.x, and it matches 2.22.0 anyway so it does not even express "never -# 2.22.0". The previous `"2.21."` pin is the proof of that failure mode — -# 2.22.1 shipped OSV-clean and required by avro 1.12.2, yet the build sat on -# 2.21.5 until a human edited the pin by hand. Steward never proposes a -# version below the current one, so 2.22.0 is already unreachable from 2.22.1 -# and a pin buys nothing but the stranding. -# -# `updates.ignore` below is the belt-and-braces form: it names the single bad -# version instead of locking a series, so 2.23.x and beyond still flow. -updates.ignore = [ - { groupId = "com.fasterxml.jackson.core", artifactId = "jackson-core", version = "2.22.0" }, - { groupId = "com.fasterxml.jackson.core", artifactId = "jackson-databind", version = "2.22.0" } -] From f15f4483fff5e71d07f51dfe1c34b9dd152bd269 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 30 Sep 2026 16:41:19 +0200 Subject: [PATCH 3/4] build(scala): bump the toolchain to Scala 3.9.0 kyo-prelude/-schema 1.0.0-RC7 ship TASTy 28.9, produced by the Scala 3.9.0 compiler, which the 3.8.4 toolchain cannot read: TASTy file kyo/TypeMap$package.tasty could not be read ... Forward incompatible TASTy file has version 28.9, produced by Scala 3.9.0, expected stable TASTy from 28.0 to 28.8 Verified before bumping: scala3-library_3 3.9.0 and scalafix-cli_3.9.0:0.14.9 both resolve on Maven Central, so the scalafix/semanticdb lane follows the new toolchain. --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c071826f..4e104af5 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -val scala3Version = "3.8.4" +val scala3Version = "3.9.0" // ---- Publishing metadata ------------------------------------------- // From 093043c287d860dedd155310970ab385519694cb Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 30 Sep 2026 16:59:17 +0200 Subject: [PATCH 4/4] build(ci): regenerate ci.yml via githubWorkflowGenerate The hand-edit that removed the validate-steward job is replaced by the regenerated file: with .scala-steward.conf gone, sbt-typelevel 0.8.7 no longer emits the job, so the generated ci.yml matches the migrated state. --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffb30214..708d447b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -366,11 +366,6 @@ jobs: modules-ignore: cats-eo-docs_3 configs-ignore: test scala-tool scala-doc-tool test-internal - # NOTE: the sbt-github-actions-generated `validate-steward` job was removed - # here by hand as part of the Scala Steward → Dependabot migration (Dependabot - # now covers sbt). It will be dropped again by the next `sbt - # githubWorkflowGenerate`: sbt-typelevel only emits the job when - # .scala-steward.conf exists, and that file is gone. site: name: Generate Site strategy: