JetBrains Space Help

DSL Reference

The Automation DSL is a domain specific language whose goal is to help you write Space automation scripts. The DSL is based on Kotlin programming language. This means that you can use Kotlin data types and language constructs inside your scripts.

job

job is a defined task consisting of steps.

job(name: String, init: Task.() -> Unit)

Property

name: String is the name of the job

Method

init is the job content

For example:

job("Hello World!") { container(image = "hello-world") }

job.requirements

requirements specifies requirements to the job run environment.

requirements(init: ScriptJobRequirementsBuilder.() -> Unit)

Method

init function specifies requirements to the host machine:

Property

workerPool: String?: explicitly specify the desired run environment:

  • WorkerPools.SPACE_CLOUD or "space-cloud" for Space Automation Cloud.

  • WorkerPools.SELF_HOSTED or "self-hosted.default" for self-hosted workers.

If specified, overrides the Default worker pool parameter.

Property

workerType: String?: explicitly specify the desired worker instance:

  • WorkerTypes.SPACE_CLOUD_UBUNTU_LTS_REGULAR or "space-cloud.ubuntu-lts.regular" (default)

  • WorkerTypes.SPACE_CLOUD_UBUNTU_LTS_LARGE or "space-cloud.ubuntu-lts.large"

If specified, overrides the Default worker pool parameter.

Method

workerTags: choose the suitable run environment by user-created worker tags

Method

resources: choose the suitable run environment by resources (CPU cores and RAM) available on the host machine

For example:

job("Example") { host("Run it on macOS") { shellScript { location = "./myscript.sh" } requirements { os { type = OSType.Mac } } } }

job.container

container runs a container and executes the specified command or script inside this container.

container(image: String, init: Container.() -> Unit = {})

container(displayName: String?, image: String, init: Container.() -> Unit = {})

Property

displayName: String? is the step name displayed in the job run resutls on the Jobs page. If not specified, the image name will be shown.

Property

image: String is the name of an image on

  • Docker Hub. An image name is enough, for example: container(image = "alpine:latest")

  • Space Packages. A full image URL is required, for example: container(image = "mycompany.registry.jetbrains.space/p/mpj/mydocker/myimage")

Method

init function configures the container and runs specified commands and scripts. You can use the following methods and properties inside init:

Property

mountDir: String sets the absolute path to the directory where the Automation volume must be mounted. By default, /mnt/space. Learn more

Property

workDir: String a path to the working directory. All commands will be run from this directory. By default, the working directory is the directory with the project sources: $mountDir/work/{git-repo-name}. You can use workDir to set:

  • An absolute path to the working directory. For example:

    workDir = "/home/john-doe/myproject"

  • A relative path to the current working. For example:

    workDir = "myproject"

    will be resolved to $mountDir/work/{git-repo-name}/myproject.

Do not use workDir to get the path to the working directory in a shellScript or kotlinScript. Instead, use the JB_SPACE_WORK_DIR_PATH environment variable. Learn more

Property

user: String specifies the user account that will be used to run commands and scripts inside the container.

Method

args provides arguments for a default image command or for entrypoint

Method

entrypoint overrides a default image command with the specified one

Method

shellScript runs the specified shell script

Method

kotlinScript runs Kotlin code

Method

service runs a container with a network-accessible service, for example, a database server

Property

env sets an environment variable in the container

Method

resources limits container resources (CPU and memory)

For example:

job("Example") { // in the container with 'gradle' image container(image = "gradle") { // run 'gradle build' shellScript { content = "gradle build" } } }

job.container.args

If entrypoint is specified, args provides arguments for the entrypoint command. Otherwise, args provides arguments for the default image command (for example, set by ENTRYPOINT). Each argument must be a separate string in the args array. If you specify more than one args, only the last one will take effect.

args(vararg args: String)

For example:

job("Example args") { container(image = "alpine") { args("echo", "Hello World!") } }

job.container.cache

cache speeds up builds by caching project dependencies in a file repository. Learn more

cache(init: FileCache.() -> Unit)

Method

init function specifies cache settings:

Property

location: CacheLocation specifies the repository where the cached files must be uploaded. If not specified, Automation will use the default file repository.

CacheLocation(val name: String, val remoteBasePath: String) where name is the name of the repository in Packages; remoteBasePath is the base upload path (the resulting cache path is remoteBasePath+localPath).

Property

localPath: String specifies a path to the cached directory. Learn more

Property

storeKey: String specifies the name of the archive with cached files. The storeKey must be unique for each set of references. Learn more

Property

restoreKeys: Iterable<String> specifies fallback cache for cases when the file specified by storeKey is not found. Learn more

Property

reuploadWhenFilesChange: Boolean specifies whether to upload changed files to the cache storage. By default, true. Learn more

For example:

job("File caches") { container(displayName = "Use cache", image = "node") { cache { storeKey = "npm-{{ hashFiles('package.json') }}" restoreKeys { +"npm-master" } localPath = "node_modules/*" } // here goes the rest of the script } }

job.container.dockerRegistryConnections

dockerRegistryConnections defines Docker registries to log into before running the container step. The step can use an image from these Docker registries. This makes possible using images from registries that require authentication. Note that the corresponding registry connections should first be declared in your project settings. Learn more

dockerRegistryConnections(init: DockerRegistryConnections.() -> Unit)

Inside dockerRegistryConnections, use the unary + operator to add connections.

For example:

job("Example") { container(displayName = "Get image from private registry", image = "some.registry.com/image:1.2.3") { dockerRegistryConnections { // some-registry is the connection key // the connection contains registry URL and access credentials +"some-registry" } // here goes the rest of the script } }

job.container.entrypoint

entrypoint runs the specified command overriding the default image command. This is equivalent to Docker's ENTRYPOINT. Command arguments must be provided as separate strings in the args array . If you specify more than one entrypoint, only the last one will take effect.

entrypoint(entryPoint: String)

For example:

job("Example entrypoint") { // override the default command set in 'myImage' container(image = "myImage") { entrypoint("/bin/sh") args("echo", "Hello World!") } }

job.container.env

env lets you set environment variables in a container. Note that you can get various information about the current run context with the help of Automation environment variables.

env = Environment()

The Environment class provides a single function for setting environment variables:

Method

set(name: String, value: String)

For example:

job("Example") { container(image = "alpine") { env.set("SITE_URL", "staging.mysite.com") } }

job.container.fileArtifacts

fileArtifacts uploads file artifacts generated by the step to a file repository. Learn more

fileArtifacts(init: FileArtifact.() -> Unit)

Method

init function specifies artifact upload settings:

Property

repository: FileRepository specifies the repository where artifacts must be uploaded. If not specified, Automation will use the default file repository.

FileRepository(val name: String, val remoteBasePath: String = "") where name is the name of the repository in Packages; remoteBasePath is the base upload path (the resulting artifact path is remoteBasePath+FileArtifact.remotePath).

Property

localPath: String specifies the source path to the file artifact that must be uploaded. Learn more

Property

remotePath: String specifies the target path to the file artifact in the file repository relative to the repository.remoteBasePath.

Property

archive: Boolean specifies whether to pack the artifact to a zip archive. By default, false.

Property

optional: Boolean: if true, the job will not fail if the cached file(s) is missing. By default, false.

Property

onStatus: OnStatus specifies the condition for uploading the artifact. Possible values:

  • OnStatus.SUCCESS – (default) upload a file only if the job finishes successfully.

  • OnStatus.ERROR – upload a file only if the job finishes with an error.

  • OnStatus.ALWAYS – always upload a file.

For example:

job("Generate zip file") { container(image = "ubuntu") { // Here goes some code... fileArtifacts { localPath = "build/build.zip" remotePath = "{{ run:number }}/build.zip" } } }

job.container.fileInput

fileInput populates a file from one of the specified sources. Learn more

fileInput(init: FileInput.() -> Unit)

Method

init function specifies artifact upload settings:

Property

source: FileSource specifies a file source:

  • FileArtifact( val repositoryName: String, val path: String, var optional: Boolean = false, var extract: Boolean = false, init: FileArtifact.() -> Unit = {}, ) where:

    • name is the name of the file repository.

    • path is the path to the file, relative to the root of the file repository.

    • optional defines if the build can continue in the absence of the file.

    • extract defines if an archive should be extracted to the local path.

  • Text( val value: String ) where value is the string to populate the file's contents with.

Property

localPath: String specifies the target path where the file must be created. Learn more

For example:

job("File artifacts") { container(displayName = "Create file", image = "ubuntu") { fileInput { source = FileSource.FileArtifact("repo-name", "artifacts/remote-file.txt") localPath = "local-file.txt" } // here goes the rest of the script } }

job.container.kotlinScript

kotlinScript runs arbitrary Kotlin code. If you specify more than one kotlinScript, only the last one will be run. Note that in order to run a Kotlin script, the container image you use must include JRE/JDK 11 or later.

kotlinScript(init: ProcessKotlinScript.(ScriptAPI) -> Unit)

For example:

job("Example kotlin script") { container(image = "amazoncorretto:17-alpine") { kotlinScript { api -> if (api.gitBranch() == "refs/heads/main") { println("Running in main branch") } else { println("Running in custom branch") } } } }
job("Example script") { container(image = "amazoncorretto:17-alpine") { kotlinScript { api -> val totalMembers = api.space().teamDirectory.stats.getAllStats().totalMembers val user = ChannelIdentifier.Profile(ProfileIdentifier.Username("Anna")) val msg = ChatMessage.Text("Hi! Employees total is $totalMembers") api.space().chats.messages.sendMessage(channel = user, content = msg) } } }

kotlinScript provides access to various APIs. The APIs let you work with particular Space modules or with build tools like Gradle. Currently, the following APIs are available:

Function

Returns

Description

gradlew(vararg args: string)

Int

Runs Gradle commands using the Gradle wrapper from the project sources. For example: api.gradlew("assemble"). Learn more

spaceUrl()

String

Returns the URL of your Space instance.

gitBranch()

String

Returns the name of the current Git branch. For example, if api.gitBranch().contains("dev")

gitRevision()

String

Returns the current Git revision number. For example, if api.gitRevision() == "..."

executionNumber()

String

Returns the number of the current Automation script execution. You can use this number, for example, to generate the application version number.

projectId() and projectKey()

String

Returns the ID and the key of the current project.

spaceClientId() and spaceClientSecret()

String

Returns the current client ID and secret. These are temporary OAuth 2.0 credentials issued to the current script. The script uses them to authenticate in various Space modules. For example, you might need it to authenticate in a Packages repository in order to publish script artifacts.

parameters()

String

Lets you use parameters in Kolin scripts. Learn more

secrets()

String

Lets you use project secrets in Kolin scripts. Learn more

fileShare()

Lets you share files between job steps. Learn more

space()

Lets you work with various Space modules. For example:

  • space().chats: lets you send messages to Chats,

  • space().packages: lets you work with package repositories in Packages,

  • space().projects: lets you manage Projects,

  • and so on.

The Space modules API works through the Space HTTP API. In other words, space() is a Kotlin-based HTTP API client. Learn more

job.container.resources

resources limits the resources for a container. The default resources constraints are:

  • 2 virtual CPUs

  • 7800 MB memory

resources(init: ExplicitResources.() -> Unit)

Method

init function specifies resources constraints. You can use the following properties inside init:

Property

cpu: Any? limits computing power (in cpu units) Supports the cpu and .mcpu units. For example:

  • 250.mcpu or 0.25.cpu for .25 vCPU

  • 500.mcpu or 0.5.cpu for .5 vCPU

  • 1000.mcpu or 1.cpu for 1 vCPU

  • and so on.

Property

memory: Any? limits memory. Supports the mb and gb units for MB and GB. For example: 1024.mb or 1.gb.

For example:

job("Example") { container(image = "alpine") { resources { cpu = 1.cpu memory = 2000.mb } } }

job.container.requirements

requirements specifies requirements to the host machine that should be used to run the step. Specify requirements in case you want to run a job with a container step not in the Space cloud but on a specific worker. Learn more

requirements(init: ContainerRequirementsBuilder.() -> Unit)

Method

init function specifies requirements to the host machine:

Method

workerTags: choose the suitable worker by user-created tags

For example:

job("Example") { container(displayName = "Run in a worker", image = "amazoncorretto:17-alpine") { shellScript { location = "./myscript.sh" } requirements { workerTags("Pool1") } } }

job.container.runIf

runIf lets you run a step on a specific condition. If runIf is an empty string, false, or code block that returns 0, the step is skipped. Learn more

runIf(condition: String)

For example:

job("Example") { container(displayName = "Check branch", image = "ubuntu") { kotlinScript { api -> api["isMainBranch"] = (api.gitBranch() == "refs/heads/main").toString() } } container(displayName = "Check branch", image = "ubuntu") { // This step will run only if the branch is "main" runIf("{{ isMainBranch }}") // ... } }

job.container.service

service runs a container with a network-accessible service. Learn more

service(image: String, init: Service.() -> Unit = {})

Property

image: String is the name of an image on Docker Hub, in Space Packages, or in another repository.

Method

init function configures the container and runs specified commands and scripts. You can use the following methods and properties inside init:

Method

alias(alias: String) specifies a network hostname for the container. If not specified, the hostname will be generated based on the image name.

Property

user: String specifies the user account that will be used to run commands and scripts inside the container.

Method

args provides arguments for a default image command or for entrypoint

Method

entrypoint overrides a default image command with the specified one

Method

kotlinScript runs Kotlin code

Property

env sets an environment variable in the container

Method

resources limits container resources (CPU and memory). Learn more about service resources

For example:

job("ping") { container(image = "alpine") { // ping service 5 times shellScript { content = "ping -c 5 db" } service("mysql:5.7") { alias("db") env["MYSQL_ROOT_PASSWORD"] = "pwd1234" } } }

job.container.shellScript

shellScript runs the provided shell script.

shellScript(init: ContainerShellScript.() -> Unit)

Method

init function specifies the script and script interpreter. You can use the following properties inside init:

Property

interpreter: String specifies the interpreter used to run the script. By default, /bin/sh.

Property

content: String? specifies the shell script content. This can be a multiline string.

Property

location: String? specifies a path to the shell script file. This may be an absolute path or a path relative to the working directory.

Method

args(vararg args: String), args(args: Collection<String>) provides arguments for the script file specified in location.

For example:

job("Example shell scripts") { container(image = "ubuntu") { shellScript { interpreter = "/bin/bash" content = """ echo 'echo Username: $1 Password: $2' >> /mnt/space/share/myscript.sh chmod +x /mnt/space/share/myscript.sh """ } } container(image = "ubuntu") { shellScript { location = "/mnt/space/share/myscript.sh" args("anna", "1234") } } // In job logs, we'll see 'Username: anna Password: 1234' }

Note that marking the script file as executable with chmod +x is not necessary: Automation automatically sets the 'executable' flag for the script file specified in location.

job.host

host executes the specified script directly on a host machine. This could be a hosted or a cloud worker.

host(displayName: String? = null, init: Host.() -> Unit = {})

Property

displayName: String? is the step name displayed in the job run resutls on the Jobs page.

Method

init function runs specified scripts. You can use the following methods and properties inside init:

Method

shellScript runs the specified shell script

Method

(Not yet available)


kotlinScript runs Kotlin code

Property

env sets an environment variable on the host machine

Method

requirements specifies requirements to a self-hosted worker. Only the worker that meets the requirements can run the job with this host step. Learn more

For example:

job("Example") { host("Run build") { // run msbuild shellScript { content = """ C:\"Program Files (x86)"\MSBuild\14.0\Bin\MsBuild.exe MySolution.sln """ } // on any worker with Windows requirements { type = OSType.Windows } } }

job.host.cache

cache speeds up builds by caching project dependencies in a file repository. Learn more

cache(init: FileCache.() -> Unit)

Method

init function specifies cache settings:

Property

location: CacheLocation specifies the repository where the cached files must be uploaded. If not specified, Automation will use the default file repository.

CacheLocation(val name: String, val remoteBasePath: String) where name is the name of the repository in Packages; remoteBasePath is the base upload path (the resulting cache path is remoteBasePath+localPath).

Property

localPath: String specifies a path to the cached file. Supports * wildcards.

Property

storeKey: String specifies the name of the archive with cached files. The storeKey must be unique for each set of references. Learn more

Property

restoreKeys: Iterable<String> specifies fallback cache for cases when the file specified by storeKey is not found. Learn more

Property

reuploadWhenFilesChange: Boolean specifies whether to upload changed files to the cache storage. By default, true. Learn more

For example:

job("File caches") { host { cache { storeKey = "npm-{{ hashFiles('package.json') }}" restoreKeys { +"npm-master" } localPath = "node_modules/*" } // here goes the rest of the script } }

job.host.dockerBuildPush

dockerBuildPush is a special helper block used to build and publish Docker images in self-hosted or Space Cloud workers. Learn more

dockerBuildPush(displayName: String? = null, init: DockerBuildPushAction.() -> Unit)

Property

displayName: String? specifies the step name that will be displayed in job logs.

Method

init function is a wrapper that runs docker build and docker push commands. You can use the following properties inside init:

Property

context: String? sets a path to Docker context. By default, it's a working directory.

Property

file: String? sets a path to Dockerfile relative to the project root. If file is not specified, Docker will look for the file at 'context'/Dockerfile.

Property

labels: DockerLabels sets labels for the image. Use it as string key-value storage: labels["key"] = "value"

Property

args: DockerBuildArgs sets build-time variables. Use it as string key-value storage: args["key"] = "value"

Property

target: String? sets target build stage. When specified, docker build will stop at the build stage with the provided name as if it were the final stage for the resulting image. Commands after the target stage will be skipped. This is only relevant for Dockerfiles with multiple build stages.

Property

platform: String? lets you build an image with another default platform, for example linux/arm64. See the list of possible values. The resulting images cannot provide any metadata about CPU variant due to a limitation of the OCI-image specification.

Important: A worker that runs the job might not support the specified platform.

Property

extraArgsForBuildCommand: List<String> is a raw list of arguments provided to the docker build command, e.g., extraArgsForBuildCommand = listOf("--build-arg", "HTTP_PROXY=http://10.20.30.2:1234")

Property

extraArgsForPushCommands: List<String> is a raw list of arguments provided to the docker push command.

Property

push: Boolean specifies whether the step must run the docker push command. By default, true.

Method

tags(configure: DockerTags.() -> Unit) sets image tags. Inside the tags block, use the unary + operator to add tags:

tags { +"registry.myorg.jetbrains.space/p/proj/my-registry/my-image:latest" +"registry.myorg.jetbrains.space/p/proj/my-registry/my-image:{{ run:id }}" +"ghcr.io/my-image:latest" }

For example:

job("Build and push Docker") { host("Build and push a Docker image") { dockerBuildPush { push = true context = "docker" // ./docker/Dockerfile file = "docker/Dockerfile" tags { +"mycompany.registry.jetbrains.space/p/prjkey/mydocker/myimage:1.0.${"$"}JB_SPACE_EXECUTION_NUMBER" } } } }

job.host.dockerRegistryConnections

dockerRegistryConnections defines Docker registries to log into before running the host step. This makes possible using registries that require authentication inside the host step. For example, you can publish images to such repositories. Note that the corresponding registry connections should first be declared in your project settings. Learn more

dockerRegistryConnections(init: DockerRegistryConnections.() -> Unit)

Inside dockerRegistryConnections, use the unary + operator to add connections.

For example:

job("Example") { host { dockerRegistryConnections { // some-registry-1 and -2 are the connection keys // the connection contains registry URL and access credentials +"some-registry-1" +"some-registry-2" } dockerBuildPush { tags { +"myimages/myimage:1.0.1" } } } }

job.host.env

env lets you set environment variables on the host machine. Note that you can get various information about the current run context with the help of Automation environment variables.

env = Environment()

The Environment class provides a single function for setting environment variables:

Method

set(name: String, value: String)

For example:

job("Example") { container(image = "alpine") { // one way to set env var env.set("SITE_URL", "staging.mysite.com") // another way to set env var env["USERNAME"] = "anna" } }

job.host.fileArtifacts

fileArtifacts uploads file artifacts generated by the step to a file repository. Learn more

fileArtifacts(init: FileArtifact.() -> Unit)

Method

init function specifies artifact upload settings:

Property

repository: FileRepository specifies the repository where artifacts must be uploaded. If not specified, Automation will use the default file repository.

FileRepository(val name: String, val remoteBasePath: String = "") where name is the name of the repository in Packages; remoteBasePath is the base upload path (the resulting artifact path is remoteBasePath+FileArtifact.remotePath).

Property

localPath: String specifies the source path to the file artifact that must be uploaded.

Property

remotePath: String specifies the target path to the file artifact in the file repository relative to the repository.remoteBasePath.

Property

archive: Boolean specifies whether to pack the artifact to a zip archive. By default, false.

Property

optional: Boolean if true, the job will not fail if the cached file(s) is missing. By default, false.

Property

onStatus: OnStatus specifies the condition for uploading the artifact. Possible values:

  • OnStatus.SUCCESS – (default) upload a file only if the job finishes successfully.

  • OnStatus.ERROR – upload a file only if the job finishes with an error.

  • OnStatus.ALWAYS – always upload a file.

For example:

job("Generate zip file") { host { // Here goes some code... fileArtifacts { localPath = "build/build.zip" remotePath = "{{ run:number }}/build.zip" } } }

job.host.fileInput

fileInput populates a file from one of the specified sources. Learn more

fileInput(init: FileInput.() -> Unit)

Method

init function specifies artifact upload settings:

Property

source: FileSource specifies a file source:

  • FileArtifact( val repositoryName: String, val path: String, var optional: Boolean = false, var extract: Boolean = false, init: FileArtifact.() -> Unit = {}, ) where:

    • name is the name of the file repository.

    • path is the path to the file, relative to the root of the file repository.

    • optional defines if the build can continue in the absence of the file.

    • extract defines if an archive should be extracted to the local path.

  • Text( val value: String ) where value is the string to populate the file's contents with.

Property

localPath: String specifies the target path where the file must must be created.

For example:

job("File artifacts") { host { fileInput { source = FileSource.FileArtifact("repo-name", "artifacts/remote-file.txt") localPath = "local-file.txt" } // here goes the rest of the script } }

job.host.kotlinScript

kotlinScript runs arbitrary Kotlin code.

kotlinScript(init: ProcessKotlinScript.(ScriptAPI) -> Unit)

For example:

job("Example Kotlin script") { host { kotlinScript { api -> if (api.gitBranch() == "refs/heads/main") { println("Running in main branch") } else { println("Running in custom branch") } } } }
job("Example Kotlin script") { host { kotlinScript { api -> val totalMembers = api.space().teamDirectory.stats.getAllStats().totalMembers val user = ChannelIdentifier.Profile(ProfileIdentifier.Username("Anna")) val msg = ChatMessage.Text("Hi! Employees total is $totalMembers") api.space().chats.messages.sendMessage(channel = user, content = msg) } } }

kotlinScript provides access to various APIs. The APIs let you work with particular Space modules or with build tools like Gradle. For the full list of available APIs, refer to job.container.kotlinScript

job.host.requirements

requirements specifies requirements to the host machine that should be used to run the step. Learn more

requirements(init: HostRequirementsBuilder.() -> Unit)

Method

init function specifies requirements to the host machine:

Method

workerTags: choose the suitable worker by user-created tags

Method

os: choose the suitable worker by the operating system of the host machine

Method

resources: choose the suitable worker by resources (CPU cores and RAM) available on the host machine

For example:

job("Example") { host("Run it on macOS") { shellScript { location = "./myscript.sh" } requirements { os { type = OSType.Mac } } } }

job.host.requirements.os

os specifies the required operating system. Automation will route the job only to the worker with the specified operating system. Learn more

os(configure: OSRequirementsBuilder.() -> Unit)

Method

configure function specifies requirements to the operating system:

Property

type: OSType? specifies the required OS type. Possible values:

  • OSType.Linux

  • OSType.Mac

  • OSType.Windows

Property

name: String? specifies the required OS name

Property

version: String? specifies the required OS version

Property

arch: String? specifies the required OS architecture. For example, x86 or amd64

For example:

job("Example") { host("Run it on Ubuntu") { shellScript { location = "./myscript.sh" } requirements { os { type = OSType.Linux version = "ubuntu-20.02" arch = "x86_64" } // run on Linux Mint // os { // name = "Linux Mint" // arch = "x86" // } } } }

job.host.requirements.resources

resources specifies requirements to the available system resources (CPU cores and RAM) on the host machine. Automation will route the job only to the worker with the sufficient resources. Learn more

resources(configure: ResourceRequirementsBuidler.() -> Unit)

Method

configure function specifies requirements to the available system resources:

Property

minCpu: MilliCpu? specifies the required number of CPU cores in milliCPU. For example, to require 2 CPU cores, set minCpu = 2000. Otherwise, you can explicitly specify the measurement units: mcpu for milliCPU or cpu for CPU. For example, minCpu = 2.cpu

Property

minMemory: Capacity? specifies the required amount of RAM in MB. For example, to require 1024MB, set minMemory = 1024. Otherwise, you can explicitly specify the measurement units: kb, mb, or gb. For example, minMemory = 1.gb

For example:

job("Example") { host("Run it on Ubuntu") { shellScript { location = "./myscript.sh" } requirements { resources { minCpu = 4000 minMemory = 10.gb } } } }

job.host.requirements.workerTags

workerTags specifies the required tag(s). Automation will route the job only to the worker that is marked with the specified tag(s). Learn more

workerTags(vararg tags: String)

For example:

job("Example") { host("Run it on machines from pool-1 and pool-2") { shellScript { location = "./myscript.sh" } requirements { workerTags("pool-1", "pool-2") } } }

job.host.runIf

runIf lets you run a step on a specific condition. If runIf is an empty string, false, or code block that returns 0, the step is skipped. Learn more

runIf(condition: String)

For example:

job("Example") { host { kotlinScript { api -> api["isMainBranch"] = (api.gitBranch() == "refs/heads/main").toString() } } host { // This step will run only if the branch is "main" runIf("{{ isMainBranch }}") // ... } }

job.host.shellScript

shellScript runs the specified shell script.

shellScript(displayName: String? = null, init: HostShellScript.() -> Unit)

Property

displayName: String? specifies the step name that will be displayed in job logs.

Method

init function specifies the script and script interpreter. You can use the following properties inside init:

Property

interpreter: String? specifies the interpreter used to run the script. If null, the default interpreter will be used:

  • /bin/sh on Linux and macOS

  • cmd on Windows

Property

content: String? specifies the shell script content. This can be a multiline string.

Property

location: String? specifies a path to the shell script file. This may be an absolute path or a path relative to the working directory.

Method

args(vararg args: String), args(args: Collection<String>) provides arguments for the script file specified in location.

For example:

job("Job with host and container") { host("Prepare myscript.sh") { shellScript { interpreter = "/bin/bash" content = """ echo Username: $1' >> ../../share/myscript.sh echo Password: $2' >> ../../share/myscript.sh chmod +x ../../share/myscript.sh """ } } // it's fine to use both 'host' and 'container' in one job container(image = "ubuntu") { shellScript { location = "/mnt/space/share/myscript.sh" args("anna", "1234") } } // In job logs, we'll see 'Username: anna Password: 1234' }

Note that marking the script file as executable with chmod +x is not necessary: Automation automatically sets the 'executable' flag for the script file specified in location.

job.git

git lets you specify Git repository checkout options. There are two main use-cases of the git item:

git(init: DefaultGitRepository.() -> Unit = {})

git(repositoryName: String, init: ExternalGitRepository.() -> Unit = {})

Property

repository: String is the name of a Git repository. For the DefaultGitRepository (the one that contains the currently running .space.kts script), omit the repository argument. For example: git {...}

Method

init function specifies the repository checkout options. You can use the following properties inside init:

Property

cloneDir: String specifies the checkout path for the repository relative to the /mnt/space/work directory.


(Available only for ExternalGitRepository)

Property

depth: Int specifies the depth of the repository commit history (the number of the last commits that must be fetched). By default, 1. To fetch all commits from the history, specify the UNLIMITED_DEPTH value.

Property

refSpec: String specifies the exact repository branch name, revision number, or Git refspec map format.

Property

clone: Boolean specifies whether to clone the project repository to the disk that is mounted to containers. By default, true. If a job is not supposed to anyhow work with the project code, set clone = false. This will reduce the job run time.

Property

env: MutableMap<String, String> = mutableMapOf() specifies environment variables provided to Git when cloning the repository. This is in addition to the default environment variables set by Automation, e.g., GIT_SSH_COMMAND. The environment variables provided here override the predefined ones. Learn more

For example:

job("git checkout") { git { // get all commits for the main repo depth = UNLIMITED_DEPTH } // checkout repo-2 as well git("repo-2") { // put it inside /mnt/space/work/secondRepo cloneDir = "secondRepo" // fetch the new-feature branch (not check out!) refSpec = "new-feature" } container(image = "alpine") { shellScript { content = """ echo Checked-out repos: ls /mnt/space/work echo Working dir: pwd """ // Checked-out repos: // /mnt/space/work/main-project-repo // /mnt/space/work/secondRepo // Working dir: // /mnt/space/work/main-project-repo } } }

job.parallel

By default, all container steps are executed sequentially inside a job. To execute them in parallel, put them inside a parallel block.

parallel(init: StepFork.() -> Unit)

Method

init function contains the run blocks that must be run in parallel. By using the sequential method of the StepFork class, you can execute container steps sequentially inside parallel.

For example:

job("Example") { // I run before others container(displayName = "Step 1", image = "alpine") { args("echo", "1") } parallel { // I run after 'Step 1' container(displayName = "Step 2", image = "alpine") { args("echo", "2") } // I run along with 'Step 2' container(displayName = "Step 3", image = "alpine") { args("echo", "3") } } }

job.parallel.sequential

sequential executes container steps inside the parallel block sequentially.

sequential(init: StepSequence.() -> Unit)

Method

init function contains the container steps that must be run sequentially.

For example:

job("Example") { // I run before others container(displayName = "Step 1", image = "alpine") { args("echo", "1") } parallel { // I run after 'Step 1' container(displayName = "Step 2", image = "alpine") { args("echo", "2") } sequential { // I run along with 'Step 2' container(displayName = "Step 3", image = "alpine") { args("echo", "3") } // I run after 'Step 3' and along with 'Step 2' container(displayName = "Step 4", image = "alpine") { args("echo", "4") } } } }

job.parameters

The parameters block let you define job parameters as well as reference project secrets and parameters. Learn more

parameters(init: Parameters.() -> Unit)

Method

init function defines secrets and parameters using the methods of the Parameters class:

Method

text(...) defines plain text parameters. Learn more

The function accepts the following arguments:

name: String is a parameter name. To reference the parameter in the script, specify its name in any string using double curly braces notation: {{ parameter-name }}

value: String? = null is a parameter value.

description: String? = null is a description that will be shown in the custom run window.

multiline: Boolean = false specifies whether the parameter can accept multiline string values. Relevant for the custom run option.

allowCustomRunOverride: Boolean = true specifies whether a user can change the parameter value for the custom run.

Method

secret(...) references a project secret. Learn more. The function accepts the following arguments:

name: String is a parameter name. To reference the parameter in the script, specify its name in a string using double curly braces notation: {{ parameter-name }}.

value: String? = null is a parameter value. Typically, this must be a reference to a project secret, e.g., {{project:auth-token}}.

description: String? = null is a description that will be shown in the custom run window.

allowCustomRunOverride: Boolean = true specifies whether a user can change the parameter value for the custom run.

For example:

job("Create configured param") { parameters { text("my-param", value = "here goes value") } container("ubuntu") { shellScript { content = "echo {{ my-param }}" } } // Output: // here goes value }

job.startOn

The startOn block contains events that trigger the job.

startOn(init: Triggers.() -> Unit)

Method

init function sets the corresponding triggers using methods of the Triggers class:

For example:

job("example") { startOn { codeReviewOpened{} } }

job.startOn.gitPush

gitPush runs the job after a commit is pushed to the project repository. By default, the gitPush trigger is enabled for a project. Important: Once you add any other trigger to the job, the gitPush trigger will be disabled.

gitPush(init: GitPushTrigger.() -> Unit)

Method

init function configures the trigger. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the trigger. true by default

Method

anyBranch() specifies that the trigger is enabled for all branches. Learn more

Method

anyBranchMatching(filter: BranchMatcherBuilder.() -> Unit) specifies the filter by a branch name. Supports include (+) and exclude (-) rules, and the asterisk (*) wildcards. Learn more

Method

anyTag() specifies that the trigger is enabled for all tags. Learn more

Method

anyTagMatching(filter: TagMatcherBuilder.() -> Unit) specifies the filter by a tag name. Supports include (+) and exclude (-) rules, and the asterisk (*) wildcards. Learn more

Method

anyRef() specifies that the trigger is enabled for all refs. Basically any Git push be it a branch, commit, tag, or any other ref will trigger the job. Learn more

Method

anyRefMatching(filter: RefMatcherBuilder.() -> Unit) specifies the filter by full ref name. Supports include (+) and exclude (-) rules, Kotlin regular expressions (Regex), and the asterisk (*) wildcards. Specify the full ref path, for example, +"refs/heads/main" Learn more

Method

pathFilter(filter: PathFilter.() -> Unit) specifies the filter by a certain directory or file name. Supports include (+) and exclude (-) rules, the asterisk (*) and double-asterisk (**) wildcards. Learn more

Property

repository: String specifies a project repository where a job must track changes. The job is started after changes are committed to the specified repository. Learn more

For example:

job("example") { startOn { // Trigger job on changes in all 'release-*' branches // excluding 'release-main' and release branches // with numbers like 'release-42' // The changes must be only in 'src/mainModule/' and // its subdirectories, but not in the 'myfile.kt' files gitPush { anyBranchMatching { +"release-*" -"release-main" } pathFilter { +"src/mainModule/**" -"**/myfile.kt" } } } }

job.startOn.schedule

Runs the job on schedule. For example, once a day at a certain time (UTC timezone).

schedule(init: ScheduleTrigger.() -> Unit)

Method

init function configures the trigger. You can use the following methods and properties inside init:

Property

enabled: Boolean enables/disables the trigger. true by default

Method

cron(expression: String) sets the trigger time (UTC) using the crontab format (MIN HOUR DAY MONTH DAYOFWEEK). You can specify more than one cron inside schedule.

For example:

job("example") { startOn { // every day at 08 AM UTC schedule { cron("0 8 * * *") } } }

job.startOn.gitBranchDeleted

gitBranchDeleted runs the job when a git branch is deleted from the project repository. Works only in the project's default branch (main).

gitBranchDeleted(init: GitBranchDeletedTrigger.() -> Unit = {})

Method

init function configures the trigger. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the trigger. true by default

Method

anyBranch() specifies that the trigger is enabled for all branches. Learn more

Method

anyBranchMatching(filter: BranchMatcherBuilder.() -> Unit) specifies the filter by a branch name. Supports include (+) and exclude (-) rules, and the asterisk (*) wildcards. Learn more

Method

anyTag() specifies that the trigger is enabled for all tags. Learn more

Method

anyTagMatching(filter: TagMatcherBuilder.() -> Unit) specifies the filter by a tag name. Supports include (+) and exclude (-) rules, and the asterisk (*) wildcards. Learn more

Method

anyRef() specifies that the trigger is enabled for all refs. Basically any Git push be it a branch, commit, tag, or any other ref will trigger the job. Learn more

Method

anyRefMatching(filter: RefMatcherBuilder.() -> Unit) specifies the filter by full ref name. Supports include (+) and exclude (-) rules, Kotlin regular expressions (Regex), and the asterisk (*) wildcards. Specify the full ref path, for example, +"refs/heads/main" Learn more

For example:

job("example") { startOn { gitBranchDeleted { anyRefMatching +"refs/heads/*new-feature*" -"refs/heads/my-new-feature" } } } }

job.startOn.codeReviewOpened

codeReviewOpened runs the job when a code review is opened in the project.

codeReviewOpened(init: CodeReviewOpenedTrigger.() -> Unit = {})

Method

init function configures the trigger. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the trigger. true by default

Property

branchToCheckout: CodeReviewBranch specifies which branch the job will check out. Possible values:

  • CodeReviewBranch.MERGE_REQUEST_SOURCE – check out the source branch if this code review is a merge request, or the default branch of the repository (typically, main) if it's a code review for a set of commits.

  • CodeReviewBranch.MERGE_REQUEST_TARGET – check out the target branch if this code review is a merge request, or the default branch of the repository (typically, main) if it's a code review for a set of commits.

  • CodeReviewBranch.REPOSITORY_DEFAULT – check out the default project repository (typically, main).

For example:

job("example") { startOn { codeReviewOpened{ branchToCheckout = CodeReviewBranch.MERGE_REQUEST_SOURCE } } }

job.startOn.codeReviewClosed

codeReviewClosed runs the job when a code review is closed in the project.

codeReviewClosed(init: CodeReviewClosedTrigger.() -> Unit = {})

Method

init function configures the trigger. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the trigger. true by default

Property

branchToCheckout: CodeReviewBranch specifies which branch the job will check out. Possible values:

  • CodeReviewBranch.MERGE_REQUEST_SOURCE – check out the source branch if this code review is a merge request, or the default branch of the repository (typically, main) if it's a code review for a set of commits.

  • CodeReviewBranch.MERGE_REQUEST_TARGET – check out the target branch if this code review is a merge request, or the default branch of the repository (typically, main) if it's a code review for a set of commits.

  • CodeReviewBranch.REPOSITORY_DEFAULT – check out the default project repository (typically, main).

For example:

job("example") { startOn { codeReviewClosed{ branchToCheckout = CodeReviewBranch.MERGE_REQUEST_SOURCE } } }

job.failOn

The failOn block contains conditions under which a job will be considered failed. By default, failed tests and non-zero exit code are failure conditions.

failOn(init: FailureConditions.() -> Unit)

Method

init function sets the corresponding failure conditions using methods of the FailureConditions class:

Method

nonZeroExitCode: default condition

Method

testFailed: default condition

Method

outOfMemory: default condition

Method

timeOut: default condition

job("example") { failOn { testFailed { enabled = false } } }

job.failOn.nonZeroExitCode

With nonZeroExitCode, the job is considered failed when it returns nonzero status code. It is a default failure condition.

nonZeroExitCode(init: NonZeroExitCodeCondition.() -> Unit)

Method

init function configures the condition. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the condition. true by default

job("example") { failOn { // disable nonzero code condition nonZeroExitCode { enabled = false } } }

job.failOn.testFailed

With testFailed, the job is considered failed if at least one test fails during the job run. It is a default failure condition. Automation detects failed tests by parsing the job output. Currently, only Gradle test output is supported.

testFailed(init: TestFailedCondition.() -> Unit)

Method

init function configures the condition. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the condition. true by default

For example:

job("example") { failOn { // disable testFailed condition testFailed { enabled = false } } }

job.failOn.outOfMemory

With outOfMemory, the job is considered failed if any of job containers runs out of memory (based on the OOMKilled event). It is a default failure condition.

outOfMemory(init: OutOfMemoryCondition.() -> Unit)

Method

init function configures the condition. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the condition. true by default

For example:

job("example") { failOn { // disable outOfMemory condition outOfMemory { enabled = false } } }

job.failOn.timeOut

With timeOut, the job is considered failed if it cannot start within the specified time period or runs longer than the specified time period. To specify the timeouts period, you should use the timeOutInMinutes keyword inside timeOut. The default and maximum allowed timeout is 120 minutes.

timeOut(init: TimeOutFailedCondition.() -> Unit)

Method

init function configures the condition. You can use the following properties inside init:

Property

enabled: Boolean enables/disables the condition. true by default

Property

runningTimeOutInMinutes: Int or timeOutInMinutes (Deprecated) defines how much time in minutes the job is allowed to run. After the timeout expires, the job is considered failed. 120 by default. Cannot be larger than 120

Property

waitingToStartTimeOutInMinutes: Int defines how much time in minutes the job can spend in the pending state before the actual run. There is a number of reasons for the pending state, for example, the amount of already running jobs available for your subscription plan has reached the limit, there are no available machines in the cloud pool, and so on. 60 by default. Cannot be larger than 60

For example:

job("example") { failOn { // fail after 15 minutes timeOut { runningTimeOutInMinutes = 15 } } }

job.volumeSize

volumeSize sets the size of the disk mounted to a container. The disk contains project repository. By default, 5 GiBs. Supports the mb and gb units for MB and GB. For example, 10000.mb or 10.gb.

volumeSize: Any?

For example:

job("example") { // mount 10GB volume volumeSize = 10.gb }

job.kaniko

kaniko is a special step used to build and publish Docker images. The step runs in a container based on a custom image with the Kaniko tool. Learn more

kaniko(init: KanikoStep.() -> Unit)

Method

init function lets you run docker build and docker publish commands:

Method

beforeBuildScript(init: ContainerShellScript.() -> Unit) runs a shell script specified in init. The script is run before build. Uses /busybox/sh.

Method

build(init: KanikoBuild.() -> Unit) runs docker build with properties specified in init:

Property

context: String? sets a path to Docker context. By default, it's a working directory.

Property

dockerfile: String? sets a path to Dockerfile relative to context. This option is equivalent to the Kaniko's --dockerfile argument.

Property

labels: DockerLabels sets labels for the image. Use it as string key-value storage: labels["key"] = "value"

Property

args: DockerBuildArgs sets build-time variables. Use it as string key-value storage: args["key"] = "value"

Property

target: String? sets target build stage. When specified, docker build will stop at the build stage with the provided name as if it were the final stage for the resulting image. Commands after the target stage will be skipped. This is only relevant for Dockerfiles with multiple build stages.

Property

customPlatform: String? lets you build an image with another default platform, for example linux/arm64. See the list of possible values. This option is a counterpart of the customPlatform Kaniko option. You can also specify a CPU variant by adding it as a third parameter, for example, "linux/arm/v5". Currently, CPU variants are only known to be used for the ARM architecture as listed here. The resulting images cannot provide any metadata about CPU variant due to limitations of the OCI-ima ge specification.

Important: A worker that runs the job might not support the specified platform.

Method

registryMirrors(vararg mirrors: String), registryMirrors(mirrors: Collection<String>), registryMirrors(configure: DockerRegistryMirrors.() -> Unit) add registry mirrors on top of the default index.docker.io. If an image is not found in the first mirror, Kaniko will try the next one, and so on, finally falling back on the default registry. For example:

registryMirrors { +"mirror.gcr.io" if (runningOnAws) { +"public.ecr.aws" } }

Method

push(name: String, init: (DockerPush.() -> Unit)? = null) runs docker push:

Property

name: String sets an image name. Must include registry URL. For example: mycompany.registry.jetbrains.space/mydocker/myimage

Method

init function lets you specify additional docker push settings:

Method

tags(vararg tagNames: String), tags(tagNames: Collection<String>), tags(configure: DockerTags.() -> Unit) sets image tags. To add tags, use the unary + operator:

tags { +"my-tag" if (isProductionBuild) { +"latest" } }

Method

resources(init: ExplicitResources.() -> Unit) lets you specify container resources in the same way as job.container.resources

For example:

job("Build and push Docker") { container(displayName = "Build sources", image = "amazoncorretto:17-alpine") { shellScript { content = """ ./gradlew build cp output mnt/space/share """ } } kaniko { beforeBuildScript { content = "cp mnt/space/share docker" } build { context = "docker" // ./docker/config/Dockerfile dockerfile = "config/Dockerfile" labels["vendor"] = "mycompany" args["HTTP_PROXY"] = "http://10.20.30.2:1234" } push("mycompany.registry.jetbrains.space/mydocker/myimage") { tags{ +"version1.0" +"stable" } } } }

job.gradlew

gradlew is a special helper item that runs Gradle commands using Gradle wrapper from the project directory. Use gradlew to simplify your build scripts. Learn more

gradlew(image: String? = null, vararg args: String, init: Project.Container.() -> Unit = {})

Property

image: String? is the name of an image on Docker Hub, in Space Packages, or in another repository. The image must include JRE/JDK 11 or later. If not specified, openjdk:latest is used.

Property

args: String specifies arguments for 'gradlew'

Method

init runs specified commands and scripts after the 'gradlew' command is run

For example:

job("Example") { // run 'gradlew build' gradlew(null, "build") }

job.warmup (Deprecated)

warmup lets you prepare warm-up data for dev environments.

warmup(ide: Ide, profileId: String? = null, init: Warmup.() -> Unit = {})

Property

ide: Ide specifies an IDE for remote development. During the warm-up, Space builds project indexes in the format compatible with the specified IDE. Can be: Ide.Fleet, Ide.Idea, Ide.CLion, Ide.GoLand, Ide.PhpStorm, Ide.PyCharm, Ide.RubyMine, Ide.WebStorm, and Ide.Rider.

Property

profileId: String? (Optional) is a warm-up data identifier. You can use it to distinguish different warm-up data in the Space UI. Currently, not available.

Method

init function lets you run warm-up scripts on specific Automation workers:

Property

devfile: String? specifies the path to the project's devfile. To prepare the warm-up data, the job will run in a container based on the image specified in the devfile. Learn more

Property

ideVersion: IdeVersion? (Optional) specifies the IDE version Space must build indexes for. ideVersion overrides the default IDE version. Possible usage:

  • ideVersion = IdeVersion.Specific("2022.1", "Stable"): for a specific version.

  • ideVersion = IdeVersion.LatestOfQuality("EAP1"): for a specific release state.

Method

requirements(init: HostRequirementsBuilder.() -> Unit) specifies requirements to the host machine that should be used to run the warm-up script. Learn more

Property

scriptLocation: String? specifies the path to a warm-up script. The script must be a .sh file.

For example:

job("Prepare data and build indexes for IDEA") { warmup(ide = Ide.Idea) { scriptLocation = "./dev-env-warmup.sh" devfile = "./devfile.yaml" } }

job.warmup.env

env lets you set environment variables in a dev environment container. Note that you can get various information about the current run context with the help of Automation environment variables.

env = Environment()

The Environment class provides a single function for setting environment variables:

Method

set(name: String, value: String)

For example:

job("My project warmup data") { warmup(ide = Ide.Fleet, profileId = "fleet") { // some env var that might be needed for the script env["USERNAME"] = "SpaceUser" requirements { workerTags("fleet") } scriptLocation = "./dev-env-warmup.sh" } }

Last modified: 15 December 2023