In mill v0.9.9 Task Context API documentation it is said
Mill keeps a long-lived JVM server to avoid paying the cost of recurrent classloading. Because of this, running System.getenv in a task might not yield up to date environment variables, since it will be initialised when the server starts, rather than when the client executes. To circumvent this, mill’s client sends the environment variables to the server as it sees them, and the server makes them available as a Map[String, String] via the Ctx API.
So reading the up to date environment variable is straightforward:
def envVar = T.input { T.ctx.env.get("ENV_VAR") }
but how can a task do this: "mill’s client sends the environment variables to the server" so that next running tasks will see the updated environment variable?
It's almost all said. But to make it more clear: The mill client is started each time you run a mill command, therefore it can also seen the current OS environment variables. It's this client who captures these variables and sends them to the already running Mill server before executing the task graph.
Also, to make that work, it is essential to use the context API to access the system environment variable via T.ctx.env
. As this context is provided my Mill, the Mill server can access the most current environment variables. On the contrary, if you would use Javas System.getenv
API, you might see probably outdated variables (exactly those current at server start time).