Newer
Older
iw-project-support / mill-iw-support / README.md

Mill IW Support

This library provides support for using Mill build tool with Iterative Works standards and best practices. It's equivalent to our SBT infrastructure (sbt-iw-projects and sbt-iw-plugin-presets) but for Mill.

Key Components

IWMillVersions

Centralized version management for all libraries:

import works.iterative.mill.IWMillVersions

// Access specific versions
val zioVersion = IWMillVersions.zio // "2.1.16"

IWMillDeps

Standardized dependency management with proper versioning:

import works.iterative.mill.IWMillDeps

// Use individual dependencies
IWMillDeps.zio          // ivy"dev.zio::zio:2.1.16"
IWMillDeps.zioJson      // ivy"dev.zio::zio-json:0.7.36"
IWMillDeps.tapirCore    // ivy"com.softwaremill.sttp.tapir::tapir-core:1.11.16"

// Use dependency groups
IWMillDeps.zioCore      // List of core ZIO dependencies
IWMillDeps.zioAll       // List of all ZIO dependencies

IWBomModule

Bill of Materials (BOM) module for centralized dependency management:

import mill._
import works.iterative.mill._

// Define a BOM module
object bom extends IWBomModule {
  def publishVersion = "0.1.0-SNAPSHOT"
  
  def pomSettings = PomSettings(
    // Standard POM settings
  )
  
  // Override with custom dependencies if needed
  override def depManagement = T {
    super.depManagement() ++ Agg(
      ivy"com.example::custom-lib:1.0.0"
    )
  }
}

// Use the BOM in modules
object myModule extends IWScalaModule {
  // Reference the BOM module
  override def bomModuleDeps = Seq(bom)
  
  // No need to specify versions - they come from the BOM
  def ivyDeps = super.ivyDeps() ++ Agg(
    ivy"dev.zio::zio",
    ivy"dev.zio::zio-json"
  )
}

IWScalaModule

Standard module configuration for Scala projects:

import mill._
import works.iterative.mill._

object myProject extends IWScalaModule {
  // Use default Scala version (3.6.3)
  // and standard compiler options with SemanticDB enabled
  
  def ivyDeps = super.ivyDeps() ++ Agg(
    ivy"${IWMillDeps.zio}",
    ivy"${IWMillDeps.zioJson}"
  )
  
  // Standard test module configuration
  object test extends ScalaTests with TestModule.ZioTest {
    def ivyDeps = super.ivyDeps() ++ Agg(
      ivy"${IWMillDeps.zioTest}",
      ivy"${IWMillDeps.zioTestSbt}"
    )
  }
}

IWPublishModule

Standard publishing configuration for IW Maven repositories:

import mill._
import mill.scalalib.publish._
import works.iterative.mill._

object myProject extends IWScalaModule with IWPublishModule {
  def publishVersion = "0.1.0-SNAPSHOT"
  
  def pomSettings = PomSettings(
    description = "My Project",
    organization = "works.iterative",
    url = "https://github.com/iterative-works/my-project",
    licenses = Seq(License.MIT),
    versionControl = VersionControl.github("iterative-works", "my-project"),
    developers = Seq(
      Developer("dev", "Developer Name", "https://github.com/dev")
    )
  )
  
  // publishTo is automatically configured based on version
  // (snapshots vs releases)
}

Getting Started

Add the library to your build.sc file:

import $ivy.`works.iterative::mill-iw-support:0.1.0-SNAPSHOT`
import works.iterative.mill._

Then extend the appropriate traits in your module definitions:

object root extends IWScalaModule with IWPublishModule {
  // ... configuration ...
}

Dependency Management Approaches

This library provides two approaches for dependency management:

1. IWMillDeps (String Constants)

Use the IWMillDeps object to access dependency strings with correct versions:

def ivyDeps = super.ivyDeps() ++ Agg(
  ivy"${IWMillDeps.zio}",
  ivy"${IWMillDeps.zioJson}"
)

2. BOM (Bill of Materials)

Use the IWBomModule to centralize dependency versions:

// Define a BOM module
object bom extends IWBomModule {
  def publishVersion = "0.1.0-SNAPSHOT"
  def pomSettings = PomSettings(...)
}

// Use the BOM in modules
object myModule extends IWScalaModule {
  override def bomModuleDeps = Seq(bom)
  
  // No need to specify versions
  def ivyDeps = super.ivyDeps() ++ Agg(
    ivy"dev.zio::zio",
    ivy"dev.zio::zio-json"
  )
}

The BOM approach offers these advantages:

  • Enforces consistent versions across modules
  • Simplifies version updates
  • Controls transitive dependency versions
  • Makes build files cleaner (no version strings)
  • Can be published as a separate artifact

Examples

See the example directory for a complete working example.

Benefits of Using Mill

  • Faster builds through aggressive caching
  • Better IDE support with type-checked build files
  • Cleaner syntax and easier configuration
  • More intuitive dependency management
  • Easier extension with custom tasks