Gradle on CircleCI
This page is a reference for integrating Gradle with CircleCI.
CircleCI provides a Gradle orb (circleci/gradle) that simplifies building and testing Gradle projects.
The orb wraps common tasks — running Gradle with dependency caching, publishing test results, and selecting a JDK — into reusable configuration blocks.
The Gradle orb
The circleci/gradle orb (current version 4.x) provides a job and a command.
| Element | Purpose |
|---|---|
Job: |
A ready-made job that checks out code, restores the Gradle dependency cache, runs a Gradle command, saves the cache, and optionally stores test results. Suitable for most single-step builds. |
Command: |
A reusable command you can embed in your own job definition. Performs the same cache-restore → Gradle invocation → cache-save cycle, giving you control over the executor and surrounding steps. |
Minimal configuration
Using the orb job
The simplest way to build a Gradle project on CircleCI.
Add a .circleci/config.yml to your repository:
version: 2.1
orbs:
gradle: circleci/gradle@4.1
workflows:
build:
jobs:
- gradle/run:
command: build
This checks out the project, restores cached dependencies, runs ./gradlew build, and saves the updated cache.
Manual configuration (no orb)
If you prefer full control over each step, use the Gradle Wrapper directly:
version: 2.1
jobs:
build:
docker:
- image: cimg/openjdk:21.0
steps:
- checkout
- restore_cache:
keys:
- gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "build.gradle.kts" }}
- gradle-
- run:
name: Build
command: ./gradlew build --no-daemon
- save_cache:
key: gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "build.gradle.kts" }}
paths:
- ~/.gradle/caches
- ~/.gradle/wrapper
- store_test_results:
path: build/test-results
workflows:
build:
jobs:
- build
-
cimg/openjdk:21.0is CircleCI’s convenience image for JDK 21. The Gradle Wrapper supplies the Gradle distribution. -
--no-daemonavoids daemon startup overhead in short-lived containers. -
store_test_resultsparses JUnit XML reports so test counts and failures appear in the CircleCI UI.
Orb job parameters
The gradle/run job accepts several parameters to customize the build:
| Parameter | Default | Description |
|---|---|---|
|
|
Gradle tasks to execute (e.g. |
|
|
The executor to run the job on. Override to use a different JDK or a machine executor. |
|
|
Path to the Gradle project root, relative to the repository root. Useful for monorepos. |
|
(generated) |
Override the default cache key. The default incorporates |
|
|
File used in the cache checksum. Set to |
|
|
Path to JUnit XML reports, relative to |
|
|
Path to HTML reports, stored as CircleCI artifacts. |
|
|
When |
Choosing an executor
The orb’s default executor uses cimg/openjdk, which provides common JDK versions on an Ubuntu base.
Override it when you need a different JDK or an Android SDK:
version: 2.1
orbs:
gradle: circleci/gradle@4.1
executors:
jdk17:
docker:
- image: cimg/openjdk:17.0
workflows:
build:
jobs:
- gradle/run:
executor: jdk17
command: build
For Android projects, use the circleci/android orb or the cimg/android image, which bundles the Android SDK alongside a JDK.
Caching and performance
CircleCI containers are ephemeral — the filesystem is discarded after every job. There are two layers of caching to consider: the CI cache (managed by CircleCI) and the Gradle build cache (managed by Gradle).
CI dependency cache
The Gradle orb’s run_with_cache command automatically saves and restores ~/.gradle/caches and ~/.gradle/wrapper.
The default cache key incorporates the Gradle Wrapper properties and your build files, so the cache is invalidated when dependencies or the Gradle version change.
If you are not using the orb, replicate this with save_cache / restore_cache as shown in the manual configuration above.
|
Keep the cache focused on downloaded dependencies and the Wrapper distribution.
Avoid caching the entire |
Gradle build cache
The CI dependency cache stores downloaded artifacts. The Gradle build cache stores task outputs — compiled classes, test results, processed resources — and can skip tasks entirely when inputs have not changed.
For a single CircleCI job, the local build cache has limited value because each container starts clean. A remote build cache (either a Develocity instance or an HTTP build cache node) provides the biggest speedup by sharing outputs across jobs, branches, and developers.
Enable the build cache in gradle.properties:
org.gradle.caching=true
Configure a remote cache in settings.gradle[.kts].
A common pattern is to let CI push to the remote cache while developers and feature-branch jobs only pull:
buildCache {
local {
isEnabled = true
}
remote<HttpBuildCache> {
url = uri("https://my-cache-node.example.com/cache/")
isPush = System.getenv("CI") != null
}
}
CircleCI sets CI=true automatically.
Publishing Build Scans
To publish a Build Scan® for every CI build, apply the Develocity plugin in settings.gradle[.kts] and accept the terms of use:
plugins {
id("com.gradle.develocity") version "3.18.1"
}
develocity {
buildScan {
termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use"
termsOfUseAgree = "yes"
publishing.onlyIf { true }
}
}
The Build Scan URL is printed in the CircleCI job log.
|
Build Scans are especially valuable on CircleCI because the ephemeral container environment makes it difficult to inspect build outputs after the job completes. A Build Scan preserves full details — task execution timeline, dependency resolution, test results, and environment info — in a shareable link. |
Test reporting
CircleCI can parse JUnit XML reports to display test counts, durations, and failure details in the job UI.
Gradle produces these reports by default under build/test-results/.
When using the orb, set test_results_path if your reports are in a non-default location.
When configuring manually, add a store_test_results step:
- store_test_results:
path: build/test-results
For multi-project builds, use a glob path to capture reports from all subprojects:
- store_test_results:
path: .
CircleCI recursively searches for TEST-*.xml files under the given path.
Parallelism and workflows
CircleCI workflows allow you to run jobs in parallel or in sequence. A common pattern for Gradle projects splits the build and test stages:
version: 2.1
orbs:
gradle: circleci/gradle@4.1
workflows:
build-and-test:
jobs:
- gradle/run:
name: compile
command: classes testClasses
- gradle/run:
name: unit-tests
command: test
requires:
- compile
- gradle/run:
name: integration-tests
command: integrationTest
requires:
- compile
The compile job runs first; unit-tests and integration-tests run in parallel once compilation succeeds.
For CPU-intensive builds, CircleCI’s parallelism feature splits work across multiple containers.
Combine it with Gradle’s --parallel flag to maximize throughput:
- run:
name: Build
command: ./gradlew build --parallel --no-daemon
Managing credentials
Store publishing tokens, signing keys, and other secrets as CircleCI environment variables (project-level or context-level).
Access them in build.gradle[.kts] with System.getenv("VAR_NAME") or providers.environmentVariable("VAR_NAME").
publishing {
repositories {
maven {
url = uri("https://repo.example.com/releases")
credentials {
username = System.getenv("REPO_USER")
password = System.getenv("REPO_TOKEN")
}
}
}
}
Use contexts to share credentials across multiple projects while restricting access to specific teams.