JetBrains Space Help

Gradle for Java and Kotlin

Prerequisites

  • You have a project written in Java or Kotlin.

  • Your project uses Gradle. A Gradle wrapper gradlew exists in the project's root directory.

  • If you want to publish artifacts to Space Packages, make sure the project has a Maven repository.

Eligible images

Typically, all you need to build a project and run tests is execute the gradle build command in the root directory of the project. There are three ways to do this in Automation:

The next task after building the project is, typically, publishing build artifacts.

(Basic) Build the project and run tests with the Gradle wrapper

The easiest way to build a Gradle project is to use the Gradle wrapper in the project root. Note that the container image must have JRE/JDK 11 or later. For example:

job("Build and run tests") { // run 'gradlew build' gradlew("amazoncorretto:17-alpine", "build") }

If the wrapper is not found, the job will fail.

Build the project and run tests with a Kotlin script

If your build script contains complex logic written in Kotlin, you should run Gradle commands using the Space Gradle API. The best practice is to use the Gradle wrapper by calling the gradlew() function. This lets you use container images with no Gradle included (JRE/JDK is still required).

job("Build and run tests") { container(displayName = "Run gradle build", image = "amazoncorretto:17-alpine") { kotlinScript { api -> // here can be your complex logic api.gradlew("build") } } }

Build the project and run tests in a custom container image

In some cases, you may need to use a custom Docker image (e.g. stored in Packages) to perform the build. This scenario requires you to understand how Automation works under the hood. The main trick is to receive test run results and pass them to Automation. If you use gradlew command to run the build (as described above), this is solved by the special test results listener initialized in init.gradle. Thus, the bootstrap job gets an additional step: It initializes Gradle using this init.gradle file. When you run a custom Docker container, you have to do this manually, i.e. add Gradle initialization to your Automation script:

job("Build and run tests") { container(displayName = "Run gradle build", image = "mycompany.registry.jetbrains.space/p/pkey/mydocker/myimage") { shellScript { content = "gradle build --init-script $mountDir/system/gradle/init.gradle" } } }

Publish Maven artifacts to Space Packages

  1. Open the project's build.gradle file.

  2. Add the reference to the Maven plugin:

    apply plugin: 'maven-publish'
  3. In the publishing section, specify the package properties (the generated package name will be groupId:artifactId). For example, we want to publish a .jar file (for the sake of length, the section content is reduced):

    publishing { publications { maven(MavenPublication) { groupId = 'org.company' artifactId = 'sample' version = "0.9-SNAPSHOT" from components.java pom { name = 'My Library' description = 'A description of my library' ... } } } }
  4. In the publishing section, in repositories, specify the repository URL and credentials using the environment variables:

    publishing { repositories { maven { credentials { // Automation has a special account for authentication in Space // account credentials are accessible via env vars username = "$System.env.JB_SPACE_CLIENT_ID" password = "$System.env.JB_SPACE_CLIENT_SECRET" } url = "https://maven.pkg.jetbrains.space/mycompany/p/projectkey/my-maven-repo" } } }

  5. Edit the project's .space.kts file. For example:

    job("Build and publish") { container(displayName = "Run publish script", image = "gradle") { kotlinScript { api -> api.gradle("build") api.gradle("publish") } } }

Publish Maven artifacts to external repositories

Publishing artifacts to external Maven repositories is almost the same as publishing to a Space Packages repository. The only difference is that you should store credentials to the repository in the Secrets&Parameters storage.

  1. Repeat steps 1 – 3 from Publish Maven artifacts to Space Packages.

  2. Create a parameter and a secret for storing the username and password that the script must use to access the external repository.

    Secrets and parameters
  3. In build.gradle, in the publishing, repositories, specify the URL of the external repository and credentials using the environment variables:

    publishing { repositories { maven { credentials { // we'll set these env vars in .space.kts username = "$System.env.USERNAME" password = "$System.env.PASSWORD" } url = "https://externalrepo.example.com/my-maven-repo" } } }

  4. Edit the project's .space.kts file. For example:

    job("Build and publish") { container(displayName = "Run publish script", image = "gradle") { // env vars for build.gradle env["USERNAME"] = "{{ project:repo_user }}" env["PASSWORD"] = "{{ project:repo_password }}" kotlinScript { api -> api.gradle("build") api.gradle("publish") } } }

Gradle wrapper in a custom location

By default, the project's gradlew wrapper is located in the project's root directory. To be able to run the wrapper, Automation sets the execute flag for the gradlew file during the job execution. If in your project, the gradlew file is located in a different directory (for example, ./subfolder/gradlew), Automation doesn't set the flag automatically. As a result, when Automation tries to run the wrapper, the job fails with Permission denied. To solve the issue, follow the instructions below.

  1. Set the execute flag for the gradlew file in the project sources. For example, by using git (run commands in the project root):

    git update-index --chmod=+x ./subfolder/gradlew git commit -m "Make gradlew executable" git push origin main
  2. In the project's .space.kts file, set the location of the gradlew wrapper as a working directory. For example:

    job("Run gradle build") { container(displayName = "Run gradlew from another dir", image = "gradle") { // path to gradlew relative to project root workDir = "subfolder" kotlinScript { api -> api.gradlew("build") } } }
Last modified: 15 December 2023