Controlling the Environment
Introduction
This guide covers how to read environment variables passed to a pipeline, how to set environment variables for external tools, and how to make tools available on the PATH.
Reading Environment Variables
All pipeline contexts - inside pipeline {}, stage {}, and job {} blocks - provide getEnv and requireEnv for reading environment variables. Users pass extra variables to a build with -e KEY=VALUE on the command line.
getEnv returns null when the variable is not set:
val registry = getEnv("DOCKER_REGISTRY") ?: "registry.example.com"
requireEnv aborts the job with a descriptive error when the variable is missing, which is the right choice for anything the build genuinely cannot proceed without:
val token = requireEnv("DEPLOY_TOKEN")
Typed variants are available for common cases:
val port = getEnvInt("SERVER_PORT") ?: 8080
val dryRun = getEnvFlag("DRY_RUN") ?: false
val port = requireEnvInt("SERVER_PORT")
val dryRun = requireEnvFlag("DRY_RUN")
hasEnv checks presence without reading the value:
if (hasEnv("CI")) {
log("Running in CI")
}Setting Environment Variables with withEnv
Inside a job you can override environment variables for any block of code using withEnv. The change is scoped to the block - when it returns, the previous environment is restored. This works the same way as cd {} for working directories.
Pass variables as named pairs:
withEnv("GRADLE_OPTS" to "-Xmx4g", "JAVA_TOOL_OPTIONS" to "-Dfile.encoding=UTF-8") {
gradle.exec("build")
}
withEnv also affects what getEnv returns inside the block. Once the block ends, getEnv returns the original value again:
// getEnv("DEPLOY_TARGET") returns "staging" here (set by the caller)
withEnv("DEPLOY_TARGET" to "production") {
val target = getEnv("DEPLOY_TARGET") // "production"
log("Deploying to $target")
}
// getEnv("DEPLOY_TARGET") returns "staging" again
To unset a variable for the duration of the block, pass null as its value:
withEnv("CI" to null) {
// tools that behave differently when CI is set will not see it here
gradle.exec("test")
}
withEnv blocks can be nested. Each layer only changes the variables it names; everything else is inherited:
withEnv("AWS_REGION" to "eu-west-1") {
withEnv("AWS_PROFILE" to "staging") {
// Both AWS_REGION and AWS_PROFILE are set here
aws.exec("s3", "sync", "dist/", "s3://my-bucket/")
}
// AWS_PROFILE is gone, AWS_REGION is still eu-west-1
}Making Tools Available with withTools
withTools prepends a tool's installation directory to the PATH for the duration of the block. This is useful when a build plugin or script spawns a program by name and expects to find it on the PATH, rather than accepting a path as an argument.
val trivy = Trivy("0.69.3")
withTools(trivy) {
maven.exec("verify") // maven plugins that invoke `trivy` will find it
}
Multiple tools can be passed in a single call:
withTools(Trivy("0.69.3"), Helm("3.14.0")) {
maven.exec("verify")
}
withTools is implemented on top of withEnv, so it follows the same scoping rules. Outside the block, the PATH is restored to its previous value.