Dependency version drift between sbt-iw-projects and mill-iw-support #2
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
iterative-works/iw-project-support#2
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
sbt-iw-projects(IWMaterialsVersions.scala) andmill-iw-support(IWMillVersions.scala) maintain two independent lists of library versions. They have silently drifted, and real consumers now hit build breakage.Concrete incident (2026-04)
xml-rozhrani(sbt) consumes bothsbt-iw-projectsANDiw-support(the runtime library, built with Mill viamill-iw-support). Afteriw-supportwas rebuilt againstmill-iw-support 0.1.3(which bumped several libs), downstream sbt builds broke:magnum2.0.0-M12.0.0-M2Transactor→TransactorZIO, package moved). Required a code migration in consumers.zio-json0.7.430.9.0(reverted to0.7.44in mill-iw-support 0.1.4)tapir-json-zio 1.13.x, which still declareszio-json 0.7.44.tapir1.11.251.13.9ServerLog.requestHandledByInterceptor. Required consumer to add an override.mill-iw-support 0.1.3also bumpedzio-http(3.0.0-RC9 → 3.8.1),zio-cli(0.7.2 → 0.8.0),zio-prelude(RC40 → RC46), and others without validation against real consumers. The sbt side was left untouched. Every unsynchronized bump is a latent landmine.Why it hurts
sbt-iw-projects) that also depend on Mill-builtiw-supportJARs see the mismatch only at transitive-resolution time, often with confusing eviction errors rather than a clear "these versions are incompatible."Goal
Eliminate the possibility of drift between sbt-iw-projects and mill-iw-support version lists. A change to one MUST affect the other (or fail a check).
Proposed solutions
Option A — Single shared version file, generated into both plugins
Move the canonical version list into a build-tool-neutral format (plain Scala source, JSON, or TOML) in a shared location (e.g.
versions/src/main/resources/iw-versions.jsonat the monorepo root). Both plugins read from / are generated from it:IWMaterialsVersions.scala(sbt plugin) andIWMillVersions.scala(mill plugin) become either:Pros: truly one source, no duplication.
Cons: build-time complexity; adds a dependency between the two plugin builds.
Option B — Published IW BOM artifact
Publish a
iw-bomMaven artifact (Bill of Materials,pompackaging) containing all managed versions. Both plugins reference the BOM for theirV.*constants by resolving and reading the published POM at the plugin's own build time; downstream consumers can also import the BOM directly viadependencyManagement.Pros: standard Maven pattern, externally consumable, works without custom tooling.
Cons: extra release step for the BOM; the plugins still need code that maps BOM entries to their
V.fooaccessors.Option C — Convert
IWVersionsto a cross-compiled sub-projectExtract
IWVersionsinto a tiny Scala module that compiles to a pure-Scala JAR with no framework dependencies. Bothsbt-iw-projectsandmill-iw-supportdepend on it at their own build time and re-export the constants.Pros: strongly typed, compile-time guaranteed consistency.
Cons: either needs publishing (like Option B) or relies on monorepo layout where both plugins can
dependsOnthe local module.Option D — Drift-check CI job (lightweight, doesn't solve root cause)
Add a CI job that diffs
IWMaterialsVersions.scalaagainstIWMillVersions.scalaand fails if corresponding constants differ. Humans still update both manually, but they can't forget.Pros: trivial to implement, no architectural change.
Cons: still duplicated definitions; drift on version-number differences is caught, but drift via differently-named constants isn't.
Option E — Kill one of the two plugins
If the long-term direction is to standardize on a single build tool across IW projects, deprecate the other plugin and migrate its consumers. This is the nuclear option but eliminates the problem categorically.
Recommendation
Option A2 (code generation from a shared source file) if we want to keep both plugins, with Option D (drift-check CI job) as an immediate safety net until A2 is built. Option A2 because:
Immediate bridge
In the meantime,
xml-rozhranihas pinnedmagnumviadependencyOverridesin itsbuild.sbtas a workaround:This should be removed once
sbt-iw-projectscatches up.Latent landmines to audit
Before the next bump, the following
mill-iw-support 0.1.3version changes should be validated against sbt consumers:zio-http 3.0.0-RC9 → 3.8.1(major RC jump)zio-cli 0.7.2 → 0.8.0zio-prelude 1.0.0-RC40 → RC46tapir 1.11.25 → 1.13.x(caught theServerLogAPI change, there may be more)zio-interop-cats 23.1.0.5 → 23.1.0.13References
f1e96ba"chore: bump dependency versions in mill-iw-support"5934fd1"fix(versions): downgrade zio-json to 0.7.44 to match tapir 1.13.15"779db9b3"fix(versions): bump mill-iw-support to 0.1.4 for zio-json/tapir alignment"