Third-Party Plugins
The Plugins in this section are developed/maintained outside the mill git tree. This list is most likely not complete. If you wrote a Mill plugin or find that one is missing in this list, please open a pull request and add that plugin with a short description (in alphabetical order).
For details about including plugins in your build.sc
read Using Mill Plugins.
Besides the documentation provided here, we urge you to consult the respective linked plugin documentation pages. The usage examples given here are most probably incomplete and sometimes outdated! |
Additional to this list, you can also search the mill-plugin
topic on GitHub for more plugins.
Aliases
This plugin adds an opinionated way of defining aliases to Mill builds. Added aliases are global and applied to the whole build.
Project home: https://github.com/carlosedp/mill-aliases
import mill._, scalalib._
import $ivy.`com.carlosedp::mill-aliases::0.2.1`
import com.carlosedp.aliases._
object foo extends ScalaModule {
...
}
object MyAliases extends Aliases {
def testall = alias("__.test")
def compileall = alias("__.compile")
def comptestall = alias("__.compile", "__.test")
}
To show all the defined aliases:
./mill Alias/list
Run an alias:
./mill Alias/run testall
When run, each aliased task is checked if valid.
Antlr
ANTLR parser generator support for mill.
Project home: https://github.com/ml86/mill-antlr
import $ivy.`net.mlbox::mill-antlr:0.1.0`
import net.mlbox.millantlr.AntlrModule
object foo extends ScalaModule with AntlrModule {
override def antlrGrammarSources = T.sources {
Seq(os.pwd/"someGrammar.g4").map(PathRef(_))
}
}
AspectJ
AspectJ compiler support for mill.
Project home: https://github.com/lefou/mill-aspectj
import mill._
import mill.scalalib._
import mill.define._
// Load the plugin from Maven Central via ivy/coursier
import $ivy.`de.tototec::de.tobiasroeser.mill.aspectj_mill0.9:0.3.1-12-89db01
import de.tobiasroeser.mill.aspectj._
object main extends AspectjModule {
// Select the AspectJ version
def aspectjVersion = "1.9.5"
// Set AspectJ options, e.g. the language level and annotation processor
// Run `mill main.ajcHelp` to get a list of supported options
def ajcOptions = Seq("-8", "-proc:none")
}
For documentation, please refer to the project home page.
Bash Completion
Limited bash completion support.
Project home: https://github.com/lefou/mill-bash-completion
Bundler
mill-bundler
is comparable to scalajs-bundler
for SBT: It manages NPM dependencies for a Scala.js module and
bundling it. Currently Webpack and Rollup are implemented but it’s easy to use another one.
Project home: https://github.com/nafg/mill-bundler
CI Release
mill-ci-release
is a wrapper around the existing publish functionality of
Mill with the aim to making releasing your project in GitHub Actions to Maven
easier by automating common setup such as setting up gpg in CI, setting up
versioning, and ensuring merges to into your main branch get published as a
SNAPSHOT. If you’re coming from sbt, then you’re likely familiar with
sbt-ci-release
which this plugin
imitates.
Project home: https://github.com/ckipp01/mill-ci-release
To get started, you’ll want to use CiReleaseModule
as a drop in replacement
where you’d normally use the Mill PublishModule
and then ensure you implement
everything that PublishModule
requires.
Secondly, you’ll need to ensure you have a few environment variables correctly set in your GitHub repo. You can see detailed instuctions on which are necessary here.
Then in CI to publish you’ll simply issue a single command:
- run: mill -i io.kipp.mill.ci.release.ReleaseModule/publishAll
This will automatically grab all the artifacts that you’ve defined to publish
in your build and publish them. Your version will automatically be managed by
mill-vcs-version
and if your
version ends in -SNAPSHOT
you’re project will be published to Sonatype
Snapshots or to the normal releases if it’s a new tag.
Daemon
Use mill as a launcher for self-building systemd daemons, convenient for handling of code-as-config, or quick editing and rebuilding of code-generating templates.
Project home: https://github.com/swaldman/mill-daemon
Place the millw script from https://github.com/lefou/millw in your project directory.
import $ivy.`com.mchange::mill-daemon:0.0.1` import com.mchange.milldaemon.DaemonModule object coolproj extends RootModule with DaemonModule { override def runDaemonPidFile = Some( os.pwd / "coolproj.pid" ) }
#!/bin.bash ./millw runMainDaemon coolproj.Main "$@"
[Unit] Description=Cool Project After=syslog.target network.target [Service] Type=forking PIDFile=/opt/coolproj/coolproj.pid User=coolproj Group=coolproj WorkingDirectory=/opt/coolproj ExecStart=/opt/coolproj/rebuild-and-start Restart=on-failure [Install] WantedBy=multi-user.target
Symlink /opt/coolproj/coolproj.service
from /etc/systemd/system
, then systemctl restart coolproj
.
DGraph
Show transitive dependencies of your build in your browser.
Project home: https://github.com/ajrnz/mill-dgraph
import $ivy.`com.github.ajrnz::mill-dgraph:0.2.0`
sh> mill plugin.dgraph.browseDeps(proj)()
Docker Native-Image Packager
This plugin allows building Docker container images with GraalVM Native-Image binaries for cloud-native and fast-startup applications.
Project home: https://github.com/carlosedp/mill-docker-nativeimage
Import the plugin, extend your module with DockerNative
and configure the
parameters for your application using the DockerNativeConfig
trait in the
dockerNative
object.
import mill._, mill.scalalib._, mill.scalalib.scalafmt._
import $ivy.`com.carlosedp::mill-docker-nativeimage::0.6.0`
import com.carlosedp.milldockernative.DockerNative
object hello extends ScalaModule with DockerNative {
def scalaVersion = "3.3.0"
object dockerNative extends DockerNativeConfig {
// Native Image parameters
def nativeImageName = "hello"
def nativeImageGraalVmJvmId = T("graalvm-java17:22.3.2")
def nativeImageClassPath = runClasspath()
def nativeImageMainClass = "com.domain.Hello.Hello"
// GraalVM parameters depending on your application needs
def nativeImageOptions = Seq(
"--no-fallback",
"--enable-url-protocols=http,https",
"-Djdk.http.auth.tunneling.disabledSchemes=",
) ++ (if (sys.props.get("os.name").contains("Linux")) Seq("--static") else Seq.empty)
// Generated Docker image parameters
def baseImage = "ubuntu:22.04"
def tags = List("docker.io/myuser/helloapp")
def exposedPorts = Seq(8080)
}
}
./mill hello.dockerNative.build()
# Test run
docker run -it --rm docker.io/myuser/helloapp
# Push to a registry
./mill hello.dockerNative.push
For more details and configuration options, please refer to the project readme and also check the provided example code.
Docusaurus 2
Simple Docusaurus runner for Mill
The plugin provides a mill module that allows to build the project web site using Docusaurus 2 as a static content generator.
Project home. https://github.com/atooni/mill-docusaurus2
Ensime
Create an .ensime file for your build.
Project home: https://github.com/davoclavo/mill-ensime
import mill._
interp.repositories() =
interp.repositories() ++ Seq(coursier.MavenRepository("https://jitpack.io"))
@
import $ivy.`com.github.yyadavalli::mill-ensime:0.0.2`
You can then run the following to generate the .ensime file
mill fun.valycorp.mill.GenEnsime/ensimeConfig
Optionally, you can specify the ensime server version using the –server flag like
mill fun.valycorp.mill.GenEnsime/ensimeConfig --server "3.0.0-SNAPSHOT"
Explicit Deps
A plugin that checks that ivyDeps
and ivyCompileDeps
accurately reflect the direct dependencies of your source code.
Project home: https://github.com/kierendavies/mill-explicit-deps
build.sc
import $ivy.`io.github.kierendavies::mill-explicit-deps::0.1.0`
import io.github.kierendavies.mill.explicitdeps.ExplicitDepsModule
object foo extends ScalaModule with ExplicitDepsModule {
// ...
}
> mill foo.checkExplicitDeps
[37/37] main.checkExplicitDeps
Found undeclared dependencies: (add these to ivyDeps)
ivy"org.typelevel::cats-kernel:2.7.0",
Found unimported dependencies: (remove these from ivyDeps)
ivy"org.typelevel::cats-effect:3.3.6",
1 targets failed
main.checkExplicitDeps Found 1 undeclared dependencies, 1 unimported dependencies
Fish Completion
Limited fish completion support.
Project home: https://github.com/ckipp01/mill-fish-completions
Giter8
A plugin to test the generation of your Giter8 template and expected working targets for your template after generation.
Project home: https://github.com/ckipp01/mill-giter8
build.sc
import $ivy.`io.chris-kipp::mill-giter8::0.2.0`
import io.kipp.mill.giter8.G8Module
object g8 extends G8Module {
override def validationTargets =
Seq("example.compile", "example.fix", "example.reformat")
}
The most common target you’d then use is mill g8.validate
.
Git
A git version plugin for mill.
Project home: https://github.com/joan38/mill-git
build.sc:
import $ivy.`com.goyeau::mill-git:<latest version>`
import com.goyeau.mill.git.GitVersionedPublishModule
import mill.scalalib.JavaModule
import mill.scalalib.publish.{Developer, License, PomSettings, VersionControl}
object `jvm-project` extends JavaModule with GitVersionedPublishModule {
override def pomSettings = PomSettings(
description = "JVM Project",
organization = "com.goyeau",
url = "https://github.com/joan38/mill-git",
licenses = Seq(License.MIT),
versionControl = VersionControl.github("joan38", "mill-git"),
developers = Seq(Developer("joan38", "Joan Goyeau", "https://github.com/joan38"))
)
}
> mill show jvm-project.publishVersion
[1/1] show
[2/2] com.goyeau.mill.git.GitVersionModule.version
"0.0.0-470-6d0b3d9"
GitHub Dependency Graph Submission
A plugin to submit your mill dependency graph to GiHub through their Dependency Submission API.
Project home: https://github.com/ckipp01/mill-github-dependency-graph
The easiest way to use this plugin is with the mill-dependency-submission action. You can add it as a workflow:
name: github-dependency-graph
on:
push:
branches:
- main
jobs:
submit-dependency-graph:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: coursier/cache-action@v6
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- uses: ckipp01/mill-dependency-submission@v1
Hepek
mill-hepek
is a plugin for writing Scala `object`s to files.
It is used as a core for Hepek static site generator: https://sake92.github.io/hepek/hepek/index.html .
Project home: https://github.com/sake92/mill-hepek
Integration Testing Mill Plugins
Integration testing for mill plugins.
Project home: https://github.com/lefou/mill-integrationtest
We assume, you have a mill plugin named mill-demo
// build.sc
import mill._, mill.scalalib._
object demo extends ScalaModule with PublishModule {
// ...
}
Add a new test sub-project, e.g. itest
.
// build.sc
import $ivy.`de.tototec::de.tobiasroeser.mill.integrationtest_mill0.9:0.4.0`
import de.tobiasroeser.mill.integrationtest._
object demo extends ScalaModule with PublishModule {
// ...
}
object itest extends MillIntegrationTestModule {
def millTestVersion = "0.9.3"
def pluginsUnderTest = Seq(demo)
}
Your project should now look similar to this:
.
+-- demo/
| +-- src/
|
+-- it/
+-- src/
+-- 01-first-test/
| +-- build.sc
| +-- src/
|
+-- 02-second-test/
+-- build.sc
As the buildfiles build.sc
in your test cases typically want to access the locally built plugin(s),
the plugins publishes all plugins referenced under pluginsUnderTest
to a temporary ivy repository, just before the test is executed.
The mill version used in the integration test then used that temporary ivy repository.
Instead of referring to your plugin with import $ivy.'your::plugin:version'
,
you can use the following line instead, which ensures you will use the correct locally build plugins.
// build.sc
import $exec.plugins
Effectively, at execution time, this line gets replaced by the content of plugins.sc
, a file which was generated just before the test started to execute.
Please always refer to the official plugin documentation site for complete and up-to-date information.
JaCoCo - Code Coverage
Mill plugin to collect test coverage data with JaCoCo and generate reports.
Plugin home: https://github.com/lefou/mill-jacoco
JBake
Create static sites/blogs with JBake.
Plugin home: https://github.com/lefou/mill-jbake
JBake home: https://jbake.org
// build.sc
import mill._
import $ivy.`de.tototec::de.tobiasroeser.mill.jbake:0.1.0`
import de.tobiasroeser.mill.jbake._
object site extends JBakeModule {
def jbakeVersion = "2.6.4"
}
Generate the site:
bash> mill site.jbake
Start a local Web-Server on Port 8820 with the generated site:
bash> mill site.jbakeServe
JBuildInfo
This is a mill module similar to BuildInfo but for Java. It will generate a Java class containing information from your build.
Project home: https://github.com/carueda/mill-jbuildinfo
To declare a module that uses this plugin, extend the
com.github.carueda.mill.JBuildInfo
trait and provide
the desired information via the buildInfoMembers
method:
// build.sc
import $ivy.`com.github.carueda::jbuildinfo:0.1.2`
import com.github.carueda.mill.JBuildInfo
import mill.T
object project extends JBuildInfo {
def buildInfoMembers: T[Map[String, String]] = T {
Map(
"name" -> "some name",
"version" -> "x.y.z"
)
}
}
This will generate:
// BuildInfo.java
public class BuildInfo {
public static final String getName() { return "some name"; }
public static final String getVersion() { return "x.y.z"; }
}
-
def buildInfoMembers: T[Map[String, String]]
The map containing all member names and values for the generated class.
-
def buildInfoClassName: String
, default:BuildInfo
The name of the class that will contain all the members from
buildInfoMembers
.
-
def buildInfoPackageName: Option[String]
, default:None
The package name for the generated class.
Kotlin
Kotlin compiler support for mill.
Project home: https://github.com/lefou/mill-kotlin
// Load the plugin from Maven Central via ivy/coursier
import $ivy.`de.tototec::de.tobiasroeser.mill.kotlin_mill0.9:0.2.0`
import mill._
import mill.scalalib._
import mill.define._
import de.tobiasroeser.mill.kotlin._
object main extends KotlinModule {
// Select the Kotlin version
def kotlinVersion = "1.4.21"
// Set additional Kotlin compiler options, e.g. the language level and annotation processor
// Run `mill main.kotlincHelp` to get a list of supported options
def kotlincOptions = super.kotlincOptions() ++ Seq("-verbose")
}
For documentation please visit the mill-kotlin project page.
You will find there also a version compatibility matrix.
MDoc
Simple MDoc runner for Mill
This plugin provides a mill module that allows to execute Scala MDoc from within a mill build. Scala MDoc simply compiles properly marked Scala snippets in plain md files and optionally runs them through an interpreter, augmenting the code with the interpreter output.
Project home: https://github.com/atooni/mill-mdoc
millw
/ millw.bat
- Mill Wrapper Scripts
Small script to automatically fetch and execute mill build tool.
Project home: https://github.com/lefou/millw
millw
is a small wrapper script around mill and works almost identical to
mill, but with additional features and compatibility with Windows. It
automatically downloads a mill release into $HOME/.mill/download
.
MiMa
Check binary compatibility with mill.
Project home: https://github.com/lolgab/mill-mima
Just mix-in the Mima
trait into your ScalaModule
.
And set the previous artifacts you want to check binary compatibility.
import mill._, scalalib._
import $ivy.`com.github.lolgab::mill-mima_mill0.9:0.0.2`
import com.github.lolgab.mill.mima._
object main extends ScalaModule with Mima {
def mimaPreviousArtifacts = Agg(
ivy"my_group_id::main:my_previous_version"
)
// other settings ...
}
You can then check the binary compatibility of the module with:
> mill main.mimaReportBinaryIssues
Binary compatibility check passed.
Missinglink
missinglink check for Mill, ported from sbt-missinglink.
Project home: https://github.com/hoangmaihuy/mill-missinglink
build.sc:
import $ivy.`io.github.hoangmaihuy::mill-missinglink::<latest-version>`
import io.github.hoangmaihuy.missinglink._
object example extends MissinglinkCheckModule
Runtime missinglink check command
> mill example.missinglinkCheck
Native-Image
Build GraalVM Native-Image binaries with mill.
Project home: https://github.com/alexarchambault/mill-native-image
Import the plugin and add the NativeImage
trait to your module and set some
configuration options:
import $ivy.`io.github.alexarchambault.mill::mill-native-image::0.1.25`
import io.github.alexarchambault.millnativeimage.NativeImage
object hello extends ScalaModule with NativeImage {
def scalaVersion = "3.3.0"
def ivyDeps = ... // Your deps here
def nativeImageName = "hello"
def nativeImageMainClass = "Main"
def nativeImageGraalVmJvmId = "graalvm-java17:22.3.2"
def nativeImageClassPath = runClasspath()
def nativeImageOptions = Seq(
"--no-fallback",
"--enable-url-protocols=http,https",
"-Djdk.http.auth.tunneling.disabledSchemes=",
) ++ (if (sys.props.get("os.name").contains("Linux")) Seq("--static") else Seq.empty)
}
Then run the nativeImage
task to build the native-image binary.
> ./mill hello.nativeImage
...
------------------------------------------------------------------------------------------------------------------------
5.9s (4.9% of total time) in 32 GCs | Peak RSS: 5.71GB | CPU load: 5.84
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
/Users/myuser/repos/scala/mill-native-image/example/out/hello/nativeImage.dest/hello (executable
)
/Users/myuser/repos/scala/mill-native-image/example/out/hello/nativeImage.dest/hello.build_artifacts.txt (txt)
========================================================================================================================
Finished generating 'hello' in 2m 0s.
For more configuration options, building binaries inside Docker, a sample project and more, check the project readme.
OSGi
Produce OSGi Bundles with mill.
Project home: https://github.com/lefou/mill-osgi
import mill._, mill.scalalib._
import $ivy.`de.tototec::de.tobiasroeser.mill.osgi:0.0.5`
import de.tobiasroeser.mill.osgi._
object project extends ScalaModule with OsgiBundleModule {
def bundleSymbolicName = "com.example.project"
def osgiHeaders = T{ super.osgiHeaders().copy(
`Export-Package` = Seq("com.example.api"),
`Bundle-Activator` = Some("com.example.internal.Activator")
)}
// other settings ...
}
PowerShell Completion
Basic PowerShell completion support.
Project home: https://github.com/sake92/mill-powershell-completion
PublishM2
Since Mill 0.6.1-27-f265a4
there is a built-in publishM2Local
target in PublishModule
.
Mill plugin to publish artifacts into a local Maven repository.
Project home: https://github.com/lefou/mill-publishM2
Just mix-in the PublishM2Module
into your project.
PublishM2Module
already extends mill’s built-in PublishModule
.
File: build.sc
import mill._, scalalib._, publish._
import $ivy.`de.tototec::de.tobiasroeser.mill.publishM2:0.0.1`
import de.tobiasroeser.mill.publishM2._
object project extends PublishModule with PublishM2Module {
// ...
}
Publishing to default local Maven repository
> mill project.publishM2Local
[40/40] project.publishM2Local
Publishing to /home/user/.m2/repository
Publishing to custom local Maven repository
> mill project.publishM2Local /tmp/m2repo
[40/40] project.publishM2Local
Publishing to /tmp/m2repo
Rust JNI
A plugin for build Rust JNI code!
Project home: https://github.com/otavia-projects/mill-rust-jni
For documentation please visit the mill-rust-jni project page.
ScalablyTyped
Scalablytyped support for mill.
Project home: https://github.com/lolgab/mill-scalablytyped
Mix-in the ScalablyTyped
trait into your ScalaJSModule
and
set-up a package.json
file with your TypeScript dependencies.
import mill._, scalalib._
import $ivy.`com.github.lolgab::mill-scalablytyped::0.0.2`
import com.github.lolgab.mill.scalablytyped._
object main extends ScalaJSModule with ScalablyTyped {
// other settings ...
}
It will run ScalablyTyped and add the converted dependencies to the module’s ivyDeps
.
Scala TSI
scala-tsi support for Mill
Project home: https://github.com/hoangmaihuy/mill-scala-tsi
build.sc:
import $ivy.`io.github.hoangmaihuy::mill-scala-tsi::<latest-version>`
import io.github.hoangmaihuy.scalatsi._
object example extends ScalaModule with ScalaTsiModule {
// The classes that you want to generate typescript interfaces for
override def typescriptExports = Seq("MyClass")
// The output file which will contain the typescript interfaces
override def typescriptOutputFile = millSourcePath / "model.ts"
// Include the package(s) of the classes here
// Optionally import your own TSType implicits to override default default generated
override def typescriptGenerationImports = Seq("mymodel._", "MyTypescript._")
}
MyClass.scala:
case class MyClass(foo: String, bar: Int)
Generate Typescript command:
> mill example.generateTypescript
model.ts:
export interface IMyClass {
foo: string
bar: number
}
Scalafix
Scalafix support for mill.
Project home: https://github.com/joan38/mill-scalafix
build.sc:
import $ivy.`com.goyeau::mill-scalafix:<latest version>`
import com.goyeau.mill.scalafix.ScalafixModule
import mill.scalalib._
object project extends ScalaModule with ScalafixModule {
def scalaVersion = "2.12.11"
}
> mill project.fix
[29/29] project.fix
/project/project/src/MyClass.scala:12:11: error: [DisableSyntax.var] mutable state should be avoided
private var hashLength = 7
^^^
1 targets failed
project.fix A Scalafix linter error was reported
SCIP (SCIP Code Intelligence Protocol)
Support for generating SCIP indexes from your Mill build. This is most commonly used to power intelligent code navigation on Sourcegraph.
Project home: https://github.com/ckipp01/mill-scip
The recommended way to use mill-scip
is via the
scip-java
cli tool that can be
installed via Coursier.
cs install scip-java
Once you have scip-java
installed the following command and the root of your
Mill build will generate an index and place it at the root of your project.
scip-java index
You can also manually trigger this with Mill by doing the following:
mill --import ivy:io.chris-kipp::mill-scip::0.3.7 io.kipp.mill.scip.Scip/generate
This will then generate your index.scip
inside of
out/io/kipp/mill/scip/Scip/generate.dest/
.
Shell Completions
As Mill is a tool often used from the CLI (Command line interface), you may be also interested in installing some completion support for your preferred shell:
Spring Boot
Support packaging Spring Boot Applications with Mill.
Project home: https://github.com/lefou/mill-spring-boot
import mill._
import mill.scalalib._
import de.tobiasroeser.mill.spring.boot.SpringBootModule
object app extends MavenModule with SpringBootModule {
override def springBootToolsVersion = "2.7.13"
}
# Package as executable Spring-Boot Application
$ mill app.springBootAssembly
Universal Packager
Support universal archive packaging for Java application with Mill, ported from sbt-native-packager.
Project home: https://github.com/hoangmaihuy/mill-universal-packager
// build.sc
import $ivy.`io.github.hoangmaihuy::mill-universal-packager::<latest-version>`
import io.github.hoangmaihuy.mill.packager.archetypes.JavaAppPackagingModule
object example extends JavaAppPackagingModule {
override def packageVersion = "0.1.0"
}
# Package as zip archive with Bash start script
$ mill example.universalPackage
VCS Version
Mill plugin to derive a version from (last) git tag and edit state. It may support other VCS as well.
Project home: https://github.com/lefou/mill-vcs-version
Lots of formatting options are provided. When used with its defaults, the outcome is identical to the version scheme that Mill itself uses.
import mill._
import mill.scalalib._
// Load the plugin from Maven Central via ivy/coursier
import $ivy.`de.tototec::de.tobiasroeser.mill.vcs.version::0.1.2`
import de.tobiasroeser.mill.vcs.version.VcsVersion
object main extends JavaModule with PublishModule {
override def publishVersion: T[String] = VcsVersion.vcsState().format()
}
Zsh Completion
Limited zsh completion support.
This plugin adds ZSH shell completions to Mill.
Project home: https://github.com/carlosedp/mill-zsh-completions