Repository navigation
Migrate to sbt 2.0.8, Scala 3.9.0; webpack → vite - #10
Merged
Merged
Conversation
sbt 2 build migration: - sbt-header moved org (de.heikoseeberger -> com.github.sbt); only the new org publishes an sbt2 build. sbt-scalajs 1.22.0, caliban-codegen-sbt 3.1.5, sbt-scalajs-crossproject 1.4.0, sbt-scalafmt 2.6.2, sbt-scalafix 0.14.8, sbt-mima 1.1.6, sbt-stryker4s 1.1.1. - sbt-explicit-dependencies and sbt-revolver have no sbt2 build; both dropped. `reStart` is gone, use `run`. - `%%%` is gone: sbt-platform-deps, which defined it, has no sbt2 build, and `%%` is platform-aware under sbt 2. Infix `withSources ()` becomes `.withSources()` on the whole ModuleID. - Universal / mappings is keyed by HashedVirtualFileRef rather than File; converted via fileConverter. - dist/debugDist renamed to webDist/webDebugDist. sbt-native-packager also defines `dist`, and under sbt 2 it is a TaskKey[HashedVirtualFileRef] against our TaskKey[File]; two types under one name is a hard load error. Both are Def.uncached because File is not a cacheable task output. - Test / testGrouping is Def.uncached: Seq[Tests.Group] has no JsonFormat, and there is nothing worth caching. - excludeLintKeys for the keys sbt 2's lintUnused reports; all are plugin-defined (sbt-git's version and gitDescribedVersion/useGitDescribe, sbt-native-packager's Rpm/Debian/Universal scopes), not ours. - chuti-stlib is hand-suffixed _sjs1_3: for ivy-local layout coursier cross-versions the module directory but derives the jar name without the platform suffix, which does not exist. - scalajs-react declared VersionScheme.Always across all its modules: stlib was generated against 3.0.0 while zio-auth 3.1.7 and web pull 4.0.0. Declared rather than lowering evictionErrorLevel, so a NEW conflict still fails the build. Scala 3.9 source fix (model/shared/.../chuti/events.scala): Type ascriptions on patterns other than a plain variable or number literal are no longer supported, so the two tuple destructurings lose theirs. The right-hand sides are fully typed already, so nothing infers differently. webpack -> vite: sbt-scalajs-bundler has no sbt2 build. Vite replaces it, driven FROM sbt: the linker output path goes over in the environment rather than vite spawning `sbt print fastLinkJSOutput` and re-entering the build. - custom.webpack.config.js is deleted along with css-loader, style-loader, file-loader, url-loader and webpack-merge: vite handles CSS and asset imports natively. - Scala.js now emits ESModule + SmallModulesFor, which is what vite consumes. - Node resolution: under sbt 2 the linker output lands in target/out/sjs1/..., far from web/node_modules, so a small vite plugin re-resolves its bare imports as if they came from web/. - npmDependencies move out of build.sbt into a real web/package.json. - Rollup warnings for "use client" directives and broken sourcemaps are filtered for node_modules only, so the same warnings from our own code still surface. Dependency upgrades: caliban 3.0.0 -> 3.1.5 (the library had drifted behind its own codegen plugin), zio-auth 3.1.7, zio-json 1.0.0, zio 2.1.26, zio-http 3.11.4, zio-config 4.0.8, flyway 13.5.0, sttp 4.0.26, logback 1.6.3, mariadb 3.5.10, jsoniter 2.40.1, jwt 11.0.4, and others. `sbt clean Test/compile` and `sbt web/webDebugDist` both build with zero warnings. The test suite still fails on missing local DB config (chuti.db.dataSource.password), which is environmental and pre-existing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
The Scala CI workflow has been failing on main since at least February, dying with exit code 127 after ~10 seconds. `actions/setup-java` with `cache: 'sbt'` only caches sbt's directories -- it does not install sbt, and the runner images no longer ship it, so `sbt` was simply not found. Adds sbt/setup-sbt@v1. Also switches `debugDist` to `web/webDebugDist`: sbt-native-packager owns the `dist` key name under sbt 2, so ours were renamed in the migration. And caches web/node_modules for the vite build, keyed on package-lock.json. The `run:` block becomes a proper block scalar; as a folded string the `cd` steps were being joined onto one line, which only worked by accident of the trailing semicolons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
sbt 2 removed `config:key` in favour of `Config/key`, so every `debian:packageBin` and `universal:packageZipTarball` invocation in CI, deploy scripts and docs failed with "Not a valid key: debian". The dist/debugDist tasks were also renamed to webDist/webDebugDist in the migration (sbt-native-packager owns the `dist` name under sbt 2), and the scripts still called the old names. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
The Scala CI build got past the missing-sbt failure and then died in stLib with "Couldn't parse: Parse error at 94.27" on @types/node -- sbt-converter 1.0.0-beta44 cannot parse the TypeScript that ships in current @types/node, which arrives transitively. beta45 parses it. This is not a new pin: dmscreen, jorlan and meal-o-rama are all already on beta45 and build their stLibs fine; chuti was simply the one left behind. No stIgnore entry is needed -- none of those three ignores "node" either. Regenerating the facades surfaced one new warning: scalajs-react's StBuildingComponent is `inline`, so its call to the deprecated scala.scalajs.runtime.linkingInfo is reported at each of our call sites. Nothing here can fix that; suppressed with the same narrowly-matched -Wconf jorlan uses, so other deprecations still warn. Verified locally: stLib/publishLocal, then `sbt clean compile web/webDebugDist` -- exit 0, zero warnings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
.gitignore anchored bloop's output as /.bloop/ and /project/.bloop/, both relative to the repo root, so stLib/project/.bloop/ was not matched and a generated stlib-build.json got committed in the previous change. Unanchored to .bloop/ so it matches at any depth, and removed the stale /project/.bloop/ line it subsumes. (The other four repos were checked; none has leaked one.) Also scalafmtAll/scalafmtSbt over the build files touched by the migration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
Unquoted, `sbt compile web/webDebugDist` was parsed as a single command and failed with "Expected whitespace character / Expected '/'". Quoting each task matches what was verified locally. The stLib step now succeeds after the beta45 bump -- the job reached this line 11 minutes in. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
zio-auth is published to GitHub Packages, not Maven Central, and this build had no resolver for it. It only ever resolved where a `publishLocal` had left a copy in ~/.ivy2/local; a clean CI checkout failed with "Error downloading net.leibman:zio-auth_3:3.1.7 ... not found" against every configured repository. Adds the resolver and the matching credentials block (GitHub Packages requires auth even for public packages), mirroring what jorlan already had -- which is why jorlan's CI resolved it and these did not. Verified by hiding ~/.ivy2/local/net.leibman/zio-auth* and confirming server/update and web/update still resolve. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
CI runs sbt through the thin client (sbtn -- the log says "entering thin client - BEEP WHIRR"), which joins multiple argv entries into a single command string. `sbt compile web/webDebugDist` therefore parsed as ONE command and failed with "Expected whitespace character / Expected '/'". The plain sbt script does not do this, which is why it only ever failed on CI and never locally. Quoting each task separately, as the previous attempt did, changes nothing -- the shell strips those quotes and sbt still receives two arguments. The fix is a single argument with a semicolon. Reproduced locally with sbtn: two args exit 1 with that exact error, semicolon form exits 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
runViteBuild asked node for an 8 GB heap, tuned on a 16 GB dev machine. A GitHub runner has 7 GB total, so that gets the job SIGTERMed by the OOM killer rather than failing cleanly. Lowered to 6 GB, and it now leaves NODE_OPTIONS alone entirely when a heap size is already set, so it can be tuned per environment. Verified web/webDebugDist still builds at the 6 GB ceiling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrates the build to sbt 2.0.8 and Scala 3.9.0, and replaces sbt-scalajs-bundler (webpack) with vite.
Plugins with no sbt 2 build
reStartis gone, userun.sbt-headermoved org (de.heikoseeberger→com.github.sbt). Bumped: sbt-scalajs 1.22.0, caliban-codegen-sbt 3.1.5, sbt-scalajs-crossproject 1.4.0, sbt-scalafmt 2.6.2, sbt-scalafix 0.14.8, sbt-mima 1.1.6, sbt-stryker4s 1.1.1.sbt 2 breaking changes hit
%%%is gone. sbt-platform-deps, which defined it, has no sbt2 build;%%is platform-aware under sbt 2.Universal / mappingsis keyed byHashedVirtualFileRef, notFile— converted viafileConverter.dist/debugDistrenamed towebDist/webDebugDist. sbt-native-packager also definesdist, and under sbt 2 it is aTaskKey[HashedVirtualFileRef]against ourTaskKey[File]; two types under one name is a hard load error. Both areDef.uncached, sinceFileis not a cacheable task output.Test / testGroupingisDef.uncached—Seq[Tests.Group]has noJsonFormat, and there is nothing worth caching there anyway.excludeLintKeysfor the keyslintUnusedreports — all plugin-defined (sbt-git'sversionandgitDescribedVersion/useGitDescribe, sbt-native-packager's Rpm/Debian/Universal scopes), not ours.chuti-stlibhand-suffixed_sjs1_3— for ivy-local layout coursier cross-versions the module directory but derives the jar name without the platform suffix, which does not exist.VersionScheme.Alwaysacross all its modules — stlib was generated against 3.0.0 while zio-auth 3.1.7 and web pull 4.0.0. Declared explicitly rather than loweringevictionErrorLevel, so a NEW conflict still fails the build.Scala 3.9 source fix
model/shared/src/main/scala/chuti/events.scala— Scala 3.9 no longer allows a type ascription on a pattern that is not a plain variable or number literal, so the two tuple destructurings lose theirs. The right-hand sides are fully typed already, so nothing infers differently.webpack → vite
Vite is driven from sbt, not the reverse: the linker output path goes over in the environment rather than vite spawning
sbt print fastLinkJSOutputand re-entering the build.custom.webpack.config.jsis deleted, along with css-loader, style-loader, file-loader, url-loader and webpack-merge — vite handles CSS and asset imports natively, so that whole loader stack was only there to do what vite does out of the box.npmDependenciesmove out of build.sbt into a realweb/package.json.Under sbt 2 the linker output lands in
target/out/sjs1/..., far fromweb/node_modules, so a small vite plugin re-resolves its bare imports as if they came fromweb/. Rollup warnings for"use client"directives and broken sourcemaps are filtered fornode_modulesonly, so the same warnings from our own code still surface.Dependencies
caliban 3.0.0 → 3.1.5 — the library had drifted behind its own codegen plugin, which was already on 3.1.5. Also zio-auth 3.1.7, zio-json 1.0.0, zio 2.1.26, zio-http 3.11.4, zio-config 4.0.8, flyway 13.5.0, sttp 4.0.26, logback 1.6.3, mariadb 3.5.10, jsoniter 2.40.1, jwt 11.0.4, and others.
Verification
sbt clean Test/compileandsbt web/webDebugDistboth exit 0 with zero warnings.The test suite still fails on missing local DB config (
Missing data at chuti.db.dataSource.password) — environmental and pre-existing, not from this change.🤖 Generated with Claude Code
https://claude.ai/code/session_01FUquyESPidPbweqpxTG2ge