---
component: artifact-cache
version: "1.7"
slug: artifact-cache/configure-jenkins
canonical_url: "https://docs.develocity.ai/artifact-cache/1.7/how-to/configure-jenkins/"
title: "Configuring Jenkins"
description: "Integrate the Develocity Artifact Cache into your Jenkins pipelines using the officially supported Jenkins plugin or a custom Artifact Cache workflow setup."
keywords:
  - "Jenkins plugin"
  - "Artifact Cache"
status: current
---

<!-- llms-index: https://docs.develocity.ai/llms.txt -->

# Configuring Jenkins

<a id="preamble"></a>

This guide shows you how to integrate the Artifact Cache CLI into your Jenkins pipelines.

There are two supported ways to do this:

*   The **Develocity Artifact Cache Jenkins plugin** is the officially supported and recommended path. It wraps the Artifact Cache CLI, restores the cache before your build, and stores it afterward, from a single Pipeline step.
    
*   The **custom Artifact Cache workflow setup** requires orchestrating download and invocation of the Artifact Cache CLI binary as part of your pipeline. Use it for Freestyle jobs, which the plugin does not support, or when you need an option the plugin does not expose.
    

<a id="prerequisites"></a>

## Prerequisites

Before you begin, ensure you have:

*   Develocity Edge node (version 2.3.0+) deployed
    
*   Develocity server (version 2026.3.0+)
    
*   Develocity access key with appropriate permissions
    
*   Jenkins 2.541.3+ (core) with Pipeline support, plus the Credentials, Plain Credentials, Structs, and Pipeline: API / Basic Steps / Step API companion plugins; Freestyle jobs need the custom Artifact Cache workflow setup below
    
*   Java 21+ available on any agent that runs the plugin, configured as follows:
    
    *   Added under **Manage Jenkins > Tools** as a JDK installation with a fixed `Home` path, not an "install automatically" entry.
        
    *   The plugin only checks already-resolved JDK homes; it does not trigger installer downloads.
        
    

The custom Artifact Cache workflow setup additionally requires access to the Artifact Cache CLI binary, [served by an Edge node or hosted in your internal network](https://docs.develocity.ai/artifact-cache/1.7/download-the-cli/), and Java 21+ installed on the agent. The plugin downloads and verifies the CLI from the public `develocity.ai` release channel by default, so hosting it yourself is optional for non-air-gapped installations (see [Air-Gapped and Custom CLI Hosting](#air-gapped)).

See [System Requirements](https://docs.develocity.ai/artifact-cache/1.7/reference/requirements/) for complete details.

<a id="installing-the-plugin"></a>

## Installing the Plugin

The plugin is not listed in the Jenkins Update Center. Install it from the downloaded `.hpi` file.

<a id="downloading-and-verifying-the-hpi"></a>

### Downloading and Verifying the HPI

You can download the latest version of the plugin’s `.hpi` file and its associated files from the following links:

*   [HPI file](https://docs.develocity.ai/downloads/develocity-artifact-cache-jenkins-plugin/develocity-artifact-cache-jenkins-plugin-1.1.0.hpi)
    
*   [HPI file SHA-256 checksum](https://docs.develocity.ai/downloads/develocity-artifact-cache-jenkins-plugin/develocity-artifact-cache-jenkins-plugin-1.1.0.hpi.sha256)
    
*   [HPI file PGP signature](https://docs.develocity.ai/downloads/develocity-artifact-cache-jenkins-plugin/develocity-artifact-cache-jenkins-plugin-1.1.0.hpi.asc)
    

```shell
curl -L -o develocity-artifact-cache-jenkins-plugin-1.1.0.hpi \
  https://docs.develocity.ai/downloads/develocity-artifact-cache-jenkins-plugin/develocity-artifact-cache-jenkins-plugin-1.1.0.hpi
```

Validate the download against the checksum before installing it:

```shell
curl -L -o develocity-artifact-cache-jenkins-plugin-1.1.0.hpi.sha256 \
  https://docs.develocity.ai/downloads/develocity-artifact-cache-jenkins-plugin/develocity-artifact-cache-jenkins-plugin-1.1.0.hpi.sha256
echo "$(cat develocity-artifact-cache-jenkins-plugin-1.1.0.hpi.sha256)  develocity-artifact-cache-jenkins-plugin-1.1.0.hpi" | sha256sum --check
```

The HPI is signed the same way as the Artifact Cache CLI JAR. See [Verifying the GPG Signature](https://docs.develocity.ai/artifact-cache/1.7/download-the-cli/#verifying-the-gpg-signature) for the steps; verify the `.asc` file against the `.hpi` file instead of the JAR, using the same Gradle Inc. signing key.

<a id="manual-upload"></a>

### Manual Upload

Navigate to **Manage Jenkins > Plugins > Advanced settings** and use **Deploy Plugin** to upload the downloaded `.hpi` file directly. Restart Jenkins if prompted.

<a id="installing-with-the-jenkins-cli"></a>

### Installing With the Jenkins CLI

Install the downloaded file from the command line with the [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/):

```shell
java -jar jenkins-cli.jar -s https://jenkins.example.com/ install-plugin /path/to/develocity-artifact-cache-jenkins-plugin-1.1.0.hpi -restart
```

Replace the `-s` URL with your controller’s address, and the path with wherever you downloaded the file.

<a id="mirroring-for-air-gapped-or-managed-installs"></a>

### Mirroring for Air-Gapped or Managed Installs

For a controller with no internet access, or to provision the plugin through configuration-as-code, host the `.hpi` file and its checksum on an internal file server or artifact repository. Point your provisioning tooling, such as the [Plugin Installation Manager Tool](https://github.com/jenkinsci/plugin-installation-manager-tool) or a custom init script, at that internal copy instead of `https://docs.develocity.ai/downloads`.

<a id="updating-the-plugin"></a>

### Updating the Plugin

Download the newer `.hpi`, verify it against its checksum, then repeat the manual upload or Jenkins CLI install. Jenkins replaces the installed version and prompts for a restart. There is no in-place upgrade through the Update Center, since the plugin is not listed there.

<a id="configuration"></a>

## Configuring the Plugin

Configure the plugin by storing the Develocity access key as a Jenkins credential, and optionally setting instance-wide defaults for use across pipelines.

<a id="storing-the-access-key"></a>

### Storing the Access Key

Navigate to **Manage Jenkins > Manage Credentials** and add a Secret text credential, for example with ID `artifact-cache-access-key`. The credential’s value can be a plain Develocity access key, or the `<hostname>=<key_value>` form (multiple entries separated by `;`), so you can reuse a credential already used for that format elsewhere in your Jenkins configuration. With the `<hostname>=<key_value>` form, the plugin uses the entry for the endpoint host, whichever of `develocityUrl` or `develocityEdgeUrl` the step targets.

<a id="global-defaults"></a>

### Setting Instance-Wide Defaults

An administrator can set instance-wide defaults for the endpoint (`develocityUrl`, or `develocityEdgeUrl` in plugin 1.1.0 or later), `develocityAccessKeyCredentialId`, and `develocityTokenExpiry` under **Manage Jenkins > System**, in the **Develocity Artifact Cache** section. Setting these once avoids repeating them in every `Jenkinsfile`.

![Develocity Artifact Cache instance-wide defaults under Manage Jenkins > System](https://docs.develocity.ai/artifact-cache/1.7/how-to/configure-jenkins/../../_images/jenkins-plugin-global-config.png)

Develocity Artifact Cache Instance-Wide Defaults

Set one endpoint here, not both; a save carrying both is rejected.

The endpoint and `develocityAccessKeyCredentialId` fall back to the instance-wide defaults only as a pair: omit both from the Pipeline DSL to use them, or set both there to override them. A step naming either endpoint therefore takes neither instance-wide endpoint. `develocityTokenExpiry` falls back independently of the other two.

<a id="using-the-plugin"></a>

## Using the Plugin

The `withDevelocityArtifactCache` step takes two forms:

*   **Around a block**: used in a scripted `node` block or inside a declarative stage’s `steps`, it restores the cache before the block runs and stores it afterward.
    
*   **Around all stages**: used as a declarative pipeline’s `options` entry, with no block, it restores before the first stage and stores after the last, on the pipeline’s own top-level `agent`. This form fails, naming the missing workspace, under `agent none`, and does not apply to a stage that declares its own separate `agent`.
    

The plugin targets one Develocity endpoint: set `develocityUrl` to reach a Develocity server (passed to the CLI as `--dv-server`), or `develocityEdgeUrl` to target a Develocity Edge directly (`--dv-edge`). Provide exactly one (they are mutually exclusive), and whichever you set also identifies the host for the access key and short-lived-token exchange. `develocityEdgeUrl` requires plugin 1.1.0 or later.

The examples below use the block form inside a stage’s `steps`.

<a id="gradle"></a>

### Gradle

```groovy
pipeline {
    agent any

    stages {
        stage('Checkout repository') {
            steps {
                checkout scm
            }
        }

        stage('Build project') {
            steps {
                withDevelocityArtifactCache(
                    develocityUrl: 'https://develocity.example.com',
                    develocityAccessKeyCredentialId: 'artifact-cache-access-key'
                ) {
                    sh './gradlew build'
                }
            }
        }
    }
}
```

<a id="maven"></a>

### Maven

```groovy
pipeline {
    agent any

    stages {
        stage('Checkout repository') {
            steps {
                checkout scm
            }
        }

        stage('Build project') {
            steps {
                withDevelocityArtifactCache(
                    develocityUrl: 'https://develocity.example.com',
                    develocityAccessKeyCredentialId: 'artifact-cache-access-key'
                ) {
                    sh './mvnw install'
                }
            }
        }
    }
}
```

<a id="npm"></a>

### npm

```groovy
pipeline {
    agent any

    stages {
        stage('Checkout repository') {
            steps {
                checkout scm
            }
        }

        stage('Build project') {
            steps {
                withDevelocityArtifactCache(
                    develocityUrl: 'https://develocity.example.com',
                    develocityAccessKeyCredentialId: 'artifact-cache-access-key'
                ) {
                    sh 'npm ci && npm run build'
                }
            }
        }
    }
}
```

<a id="plugin-dsl-options"></a>

### Pipeline DSL Options

 
| Option | Description |
| --- | --- |
| `develocityUrl` | The Develocity server URL, for example https://develocity.example.com, passed to the CLI as --dv-server. Must be an http or https URL with no credentials, query string, or fragment. Mutually exclusive with develocityEdgeUrl. Required: Yes, unless develocityEdgeUrl is set instead, or a global default is set. |
| `develocityEdgeUrl` | The URL of a Develocity Edge to target directly, for example https://develocity-edge.example.com, passed to the CLI as --dv-edge. Takes the same URL forms as develocityUrl, and is mutually exclusive with it. Requires plugin 1.1.0 or later. Required: Yes, unless develocityUrl is set instead, or a global default is set. |
| `develocityAccessKeyCredentialId` | ID of the credential holding the Develocity access key. Required: Yes, unless a global default is set. |
| `develocityUrlAllowInsecure` | Allow the endpoint, whichever of develocityUrl and develocityEdgeUrl is set, to be an http URL. Default: false. |
| `develocityTokenExpiry` | Lifetime, in hours, of the short-lived Develocity token exchanged from the access key before each phase. Default: 2, or the global default. |
| `allowUntrusted` | Accept the Develocity server’s TLS certificate without verifying it; leave it off and install the certificate into the agents' trust stores instead. Default: false. |
| `imageNames` | Ordered list of image names to restore from, most preferred first. When unset, the cache phases use the default image naming the CLI already applies (see [Automatic Image Name Generation](#automatic-image-name-generation)). |
| `cacheReadOnly` | Restore from the cache but never store to it. Use it for builds that should not publish into the cache, such as pull request builds. Default: false. |
| `debug` | Write the CLI output and cache summary row to the build log even on a clean run, not only when a phase warns or errors. Default: false. |
| `cliVersion` | Pin the CLI to a specific version instead of the version this plugin bundles. Letters, digits, `.`, `_`, `+`, and `-` only. |
| `cliRepository` | Base URL to download the CLI jar from, for agents that cannot reach the public download location (see [Air-Gapped and Custom CLI Hosting](#air-gapped)). |
| `cliRepositoryAllowInsecure` | Allow cliRepository to be an http URL. Default: false. |
| `cliRepositoryHeader` | One `Name: Value` HTTP header sent with the CLI download request, for an authenticated repository. Mutually exclusive with `cliRepositoryHeaderCredentialId`. |
| `cliRepositoryHeaderCredentialId` | ID of a Secret text credential holding the header line, in the same form as `cliRepositoryHeader`. The recommended way to configure an authenticated repository, since the header value never becomes a step argument. |
| `cliSha256` | Expected SHA-256 checksum of the CLI jar, as 64 hexadecimal characters. Needed only when `cliVersion` pins a version the plugin does not already recognize. |
| `additionalCliArgs` | Extra CLI flags passed through verbatim, for options this plugin does not model, such as `--gradle-home`. Entries must not be blank. An entry setting the endpoint or the server trust, `--dv-server`, `--dv-edge`, or `--allow-untrusted-server`, is dropped: set `develocityUrl` or `develocityEdgeUrl`, and `allowUntrusted`, instead. |

Resolved options go to the controller’s log at `FINE`, not the build log. Add a log recorder on `com.gradle.develocity.artifactcache.jenkins` under **Manage Jenkins > System Log** to see them. `cliRepositoryHeader` and the values in `additionalCliArgs` are masked there, keeping only the flag names, because either can carry a secret.

<a id="air-gapped"></a>

### Air-Gapped and Custom CLI Hosting

By default, the plugin downloads the CLI jar from the public `develocity.ai` release channel and verifies it against a checksum bundled with the plugin. When the endpoint addresses an Edge node running version 2.3.0 or later, the plugin downloads the CLI jar from that Edge node instead, using the short-lived token the build already exchanged for the Restore phase. This route needs no extra configuration, and it is the same Edge-serving mechanism [Downloading From an Edge Node](https://docs.develocity.ai/artifact-cache/1.7/download-the-cli/#downloading-from-an-edge-node) describes for the custom workflow setup. An older Edge node, or an endpoint that does not address an Edge node, falls back to the public release channel automatically. To serve the CLI from your own network instead, set `cliRepository` to your mirror’s base URL. An explicit `cliRepository` always takes priority over the Edge node route. For an authenticated mirror, add a credential holding the header line and reference it with `cliRepositoryHeaderCredentialId`:

```groovy
withDevelocityArtifactCache(
    develocityUrl: 'https://develocity.example.com',
    develocityAccessKeyCredentialId: 'artifact-cache-access-key',
    cliRepository: 'https://mirror.example.com/artifact-cache-cli',
    cliRepositoryHeaderCredentialId: 'ac-repository-header'
) {
    sh './gradlew build'
}
```

The download, its checksum verification, and the local cache of the verified jar all happen on the agent that runs the build, so `cliRepository` only needs to be reachable from your agents, not from the controller.

<a id="automatic-image-name-generation"></a>

## Automatic Image Name Generation

By default, Artifact Cache CLI generates an image name automatically when neither path sets one explicitly. Automatic generation is the recommended approach: it derives the name from the build context, your project’s repository data, and the CI runner’s environment, so you do not have to choose or maintain a name yourself.

The Artifact Cache CLI inspects the following environment variables when generating image names for Jenkins:

*   `JOB_NAME`
    
*   `JENKINS_HOME`
    

<a id="overriding-the-generated-name"></a>

### Overriding the Generated Name

Set an explicit name only when you need to control the value, for example to share one cache across differently-named jobs. With the plugin, provide it through the `imageNames` option. With the custom Artifact Cache workflow setup, provide it with the `--image-name` CLI option or the `ARTIFACT_CACHE_IMAGE` environment variable.

<a id="branch-aware-caching"></a>

## Branch-Aware Caching

The plugin derives `DEVELOCITY_ARTIFACT_CACHE_BRANCH_NAME` and `DEVELOCITY_ARTIFACT_CACHE_BASE_BRANCH_NAME` for you, once per build, from the multibranch pipeline’s own `BRANCH_NAME` and `CHANGE_TARGET` variables, falling back to the Git plugin’s branch variables. No DSL option or `environment` block is needed for this.

An environment variable already set in the build, for example through `withEnv`, wins over the derived value. The custom Artifact Cache workflow setup does not derive these automatically; see [Setting the Branch Name](#branch-name-manual) below.

<a id="cache-summary"></a>

## Cache Summary

Each build the plugin instruments gets a cache summary on the build page: one row per phase, with outcome, detected tools, entry count, entry size, duration, and any warning. A build that never reaches a phase, for example because no compatible JDK was found, still gets a row naming why.

![Cache summary on a Jenkins build page](https://docs.develocity.ai/artifact-cache/1.7/how-to/configure-jenkins/../../_images/jenkins-cache-summary.png)

Cache Summary on a Jenkins Build Page

Each row names the phase (Restore or Store), whether it succeeded, the tools it detected, how many entries it restored or stored, the total entry size, and how long it took. The custom Artifact Cache workflow setup does not add this; persist the CLI log file as a build artifact instead, as shown in [Gradle Project Setup](#gradle-setup) below.

<a id="custom-artifact-cache-workflow-setup"></a>

## Custom Artifact Cache Workflow Setup

Use the custom Artifact Cache workflow setup for a Freestyle job, which the plugin does not support, or when you need a CLI option the plugin does not expose. This approach downloads the CLI and runs the `restore` and `store` commands yourself.

<a id="storing-credentials"></a>

### Storing Credentials

Navigate to **Manage Jenkins > Manage Credentials** and add:

  
| ID | Type | Value |
| --- | --- | --- |
| `artifact-cache-access-key` | Secret text | Your Develocity access key: `<hostname>=<key_value>` |
| `artifact-cache-repo` | Username with password | Credentials for your internal artifact repository |

> [!NOTE]
> If you use a custom internal artifact repository location, verify the "Provision and configure Artifact Cache" stage in your pipeline. Ensure the `curl` command’s authentication parameters (`-u`) and download URL match your repository’s requirements.

<a id="branch-name-manual"></a>

### Setting the Branch Name

For Jenkins, you must manually set the following environment variables:

*   `DEVELOCITY_ARTIFACT_CACHE_BRANCH_NAME` - The current repository branch (e.g., `main` or `feature-branch-name`)
    
*   `DEVELOCITY_ARTIFACT_CACHE_BASE_BRANCH_NAME` - The base repository branch (e.g., `main`)
    

For [multibranch pipelines](https://www.jenkins.io/doc/book/pipeline/multibranch/), set these values dynamically:

```groovy
environment {
    DEVELOCITY_ARTIFACT_CACHE_BRANCH_NAME = "${ env.BRANCH_NAME }"
    DEVELOCITY_ARTIFACT_CACHE_BASE_BRANCH_NAME = "${ env.CHANGE_TARGET }"
}
```

The values above automatically adapt for multi-branch pipelines. For regular pipelines, set them to hard-coded values:

```groovy
environment {
    DEVELOCITY_ARTIFACT_CACHE_BRANCH_NAME = "main"
    DEVELOCITY_ARTIFACT_CACHE_BASE_BRANCH_NAME = "main"
}
```

<a id="gradle-setup"></a>

### Gradle Project Setup

<a id="shared-build-logic-caching"></a>

#### Shared Build Logic Caching

Starting with Artifact Cache CLI version 1.1.0, the Setup Cache automatically caches shared Gradle build logic defined in `buildSrc` and included builds. This feature requires the [Develocity Gradle Plugin](https://docs.develocity.ai/gradle/4.6/gradle-plugin/) version 4.4.1 or later, and has the following constraints:

*   The absolute project checkout path must remain constant across builds. Jenkins uses a stable workspace path by default (`/var/lib/jenkins/workspace/<job-name>`), but renaming jobs or using custom workspace directories invalidates the cache.
    
*   The repository checkout must happen before the `restore` command.
    

<a id="complete-pipeline-example"></a>

#### Complete Pipeline Example

```groovy
pipeline {
    agent any

    environment {
        // Artifact Cache Configuration
        ARTIFACT_CACHE_CLI_VERSION = '1.7.0'
        // ARTIFACT_CACHE_IMAGE is intentionally omitted so the image name is
        // generated automatically, which is the recommended default. Set it only
        // when you need to override the generated name.
        // Develocity
        DV_SERVER = 'https://<develocity.address>'
        // Artifact Cache CLI
        ARTIFACT_CACHE_REPO = 'https://your-internal-repo.example.com/path/to/artifact-cache-cli'
        // Misc
        ARTIFACT_CACHE_CLI_FILENAME = 'develocity-artifact-cache-cli'
        ARTIFACT_CACHE_OPTS = "--gradle-home=${ env.HOME }/.gradle --reporting-directory=${ env.WORKSPACE }/.develocity/artifact-cache"
    }

    stages {
        stage('Checkout repository') {
            steps {
                checkout scm
            }
        }

        stage('Provision and configure Artifact Cache') {
            steps {
                script {
                    def jdkHome = tool name: 'jdk21', type: 'jdk'
                    def artifactCacheDir = "${ env.HOME }/.jenkins-tools/develocity/${ env.ARTIFACT_CACHE_CLI_VERSION }"
                    def artifactCacheJar = "${ artifactCacheDir }/${ env.ARTIFACT_CACHE_CLI_FILENAME }.jar"

                    withCredentials([usernamePassword(credentialsId: 'artifact-cache-repo', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
                        sh """
                        if [ ! -f "${ artifactCacheJar }" ]; then
                            echo "Downloading Artifact Cache CLI v${ env.ARTIFACT_CACHE_CLI_VERSION }..."
                            mkdir -p "${ artifactCacheDir }"
                            curl --location --fail --silent --show-error \\
                              --connect-timeout 5 --max-time 30 \\
                              --retry 3 --retry-delay 3 --retry-max-time 60 \\
                              -u "\$USER:\$PASS" \\
                              "${ env.ARTIFACT_CACHE_REPO }/com/gradle/${ env.ARTIFACT_CACHE_CLI_FILENAME }/${ env.ARTIFACT_CACHE_CLI_VERSION }/${ env.ARTIFACT_CACHE_CLI_FILENAME }-${ env.ARTIFACT_CACHE_CLI_VERSION }.jar" \\
                              --output "${ artifactCacheJar }"
                        fi
                    """
                    }

                    // Set reusable command variables
                    env.ARTIFACT_CACHE_CMD = "${ jdkHome }/bin/java -jar ${ artifactCacheJar }"
                    def imageName = env.ARTIFACT_CACHE_IMAGE ? "--image-name=${ env.ARTIFACT_CACHE_IMAGE }" : ""
                    env.ARTIFACT_CACHE_CMD_OPTS = "--dv-server=${ env.DV_SERVER } ${ imageName } ${ env.ARTIFACT_CACHE_OPTS }"
                }
            }
        }

        stage('Restore from Artifact Cache') {
            steps {
                script {
                    try {
                        withCredentials([string(credentialsId: 'artifact-cache-access-key', variable: 'DEVELOCITY_ACCESS_KEY')]) {
                            sh """
                                ${ env.ARTIFACT_CACHE_CMD } restore ${ env.ARTIFACT_CACHE_CMD_OPTS }
                            """
                        }
                    } catch (e) {
                        echo "WARNING: Could not restore the Artifact Cache. The build will proceed but may be slower."
                    }
                }
            }
        }
        stage('Build project') {
            steps {
                sh './gradlew build'
            }
        }
    }

    post {
        success {
            script {
                try {
                    withCredentials([string(credentialsId: 'artifact-cache-access-key', variable: 'DEVELOCITY_ACCESS_KEY')]) {
                        sh """
                             ${ env.ARTIFACT_CACHE_CMD } store ${ env.ARTIFACT_CACHE_CMD_OPTS }
                        """
                    }
                } catch (e) {
                    echo "WARNING: Failed to store in the Artifact Cache."
                }
            }
        }
        always {
            script {
                // Persist Artifact Cache Logs
                def logPath = ".develocity/artifact-cache/artifact-cache.log"
                if (fileExists(logPath)) {
                    archiveArtifacts artifacts: logPath, allowEmptyArchive: true, fingerprint: false
                }
            }
        }
    }
}
```

<a id="maven-setup"></a>

### Maven Project Setup

<a id="configuration-2"></a>

#### <a id="maven-configuration"></a>Configuration

Change only the `ARTIFACT_CACHE_OPTS`:

```groovy
environment {
    ARTIFACT_CACHE_OPTS = "--maven-home=${ env.HOME }/.m2"
}
```

<a id="complete-pipeline-example-2"></a>

#### Complete Pipeline Example

```groovy
pipeline {
    agent any

    environment {
        // Artifact Cache Configuration
        ARTIFACT_CACHE_CLI_VERSION = '1.7.0'
        // ARTIFACT_CACHE_IMAGE is intentionally omitted so the image name is
        // generated automatically, which is the recommended default. Set it only
        // when you need to override the generated name.
        // Develocity
        DV_SERVER = 'https://<develocity.address>'
        // Artifact Cache CLI
        ARTIFACT_CACHE_REPO = 'https://your-internal-repo.example.com/path/to/artifact-cache-cli'
        // Misc
        ARTIFACT_CACHE_CLI_FILENAME = 'develocity-artifact-cache-cli'
        ARTIFACT_CACHE_OPTS = "--maven-home=${ env.HOME }/.m2 --reporting-directory=${ env.WORKSPACE }/.develocity/artifact-cache"
    }

    stages {
        stage('Checkout repository') {
            steps {
                checkout scm
            }
        }

        stage('Provision and configure Artifact Cache') {
            steps {
                script {
                    def jdkHome = tool name: 'jdk21', type: 'jdk'
                    def artifactCacheDir = "${ env.HOME }/.jenkins-tools/develocity/${ env.ARTIFACT_CACHE_CLI_VERSION }"
                    def artifactCacheJar = "${ artifactCacheDir }/${ env.ARTIFACT_CACHE_CLI_FILENAME }.jar"

                    withCredentials([usernamePassword(credentialsId: 'artifact-cache-repo', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
                        sh """
                        if [ ! -f "${ artifactCacheJar }" ]; then
                            echo "Downloading Artifact Cache CLI v${ env.ARTIFACT_CACHE_CLI_VERSION }..."
                            mkdir -p "${ artifactCacheDir }"
                            curl --location --fail --silent --show-error \\
                              --connect-timeout 5 --max-time 30 \\
                              --retry 3 --retry-delay 3 --retry-max-time 60 \\
                              -u "\$USER:\$PASS" \\
                              "${ env.ARTIFACT_CACHE_REPO }/com/gradle/${ env.ARTIFACT_CACHE_CLI_FILENAME }/${ env.ARTIFACT_CACHE_CLI_VERSION }/${ env.ARTIFACT_CACHE_CLI_FILENAME }-${ env.ARTIFACT_CACHE_CLI_VERSION }.jar" \\
                              --output "${ artifactCacheJar }"
                        fi
                    """
                    }

                    // Set reusable command variables
                    env.ARTIFACT_CACHE_CMD = "${ jdkHome }/bin/java -jar ${ artifactCacheJar }"
                    def imageName = env.ARTIFACT_CACHE_IMAGE ? "--image-name=${ env.ARTIFACT_CACHE_IMAGE }" : ""
                    env.ARTIFACT_CACHE_CMD_OPTS = "--dv-server=${ env.DV_SERVER } ${ imageName } ${ env.ARTIFACT_CACHE_OPTS }"
                }
            }
        }

        stage('Restore from Artifact Cache') {
            steps {
                script {
                    try {
                        withCredentials([string(credentialsId: 'artifact-cache-access-key', variable: 'DEVELOCITY_ACCESS_KEY')]) {
                            sh """
                                ${ env.ARTIFACT_CACHE_CMD } restore ${ env.ARTIFACT_CACHE_CMD_OPTS }
                            """
                        }
                    } catch (e) {
                        echo "WARNING: Could not restore the Artifact Cache. The build will proceed but may be slower."
                    }
                }
            }
        }
        stage('Build project') {
            steps {
                sh './mvnw install'
            }
        }
    }

    post {
        success {
            script {
                try {
                    withCredentials([string(credentialsId: 'artifact-cache-access-key', variable: 'DEVELOCITY_ACCESS_KEY')]) {
                        sh """
                             ${ env.ARTIFACT_CACHE_CMD } store ${ env.ARTIFACT_CACHE_CMD_OPTS }
                        """
                    }
                } catch (e) {
                    echo "WARNING: Failed to store in the Artifact Cache."
                }
            }
        }
        always {
            script {
                // Persist Artifact Cache Logs
                def logPath = ".develocity/artifact-cache/artifact-cache.log"
                if (fileExists(logPath)) {
                    archiveArtifacts artifacts: logPath, allowEmptyArchive: true, fingerprint: false
                }
            }
        }
    }
}
```

<a id="custom-maven-repository-path"></a>

#### Custom Maven Repository Path

If your project uses a custom Maven repository location (via `-Dmaven.repo.local` or `settings.xml`), add the `--maven-repository` option:

```groovy
environment {
    ARTIFACT_CACHE_OPTS = "--maven-home=${ env.HOME }/.m2 --maven-repository=/custom/repo"
}
```

<a id="npm-setup"></a>

### npm Project Setup

<a id="configuration-3"></a>

#### <a id="npm-configuration"></a>Configuration

Change only the `ARTIFACT_CACHE_OPTS`:

```groovy
environment {
    ARTIFACT_CACHE_OPTS = "--npm-home=${ env.HOME }/.npm"
}
```

<a id="complete-pipeline-example-3"></a>

#### Complete Pipeline Example

```groovy
pipeline {
    agent any
    environment {
        // Artifact Cache Configuration
        ARTIFACT_CACHE_CLI_VERSION = '1.7.0'
        // ARTIFACT_CACHE_IMAGE is intentionally omitted so the image name is
        // generated automatically, which is the recommended default. Set it only
        // when you need to override the generated name.
        // Develocity
        DV_SERVER = 'https://<develocity.address>'
        // Artifact Cache CLI
        ARTIFACT_CACHE_REPO = 'https://your-internal-repo.example.com/path/to/artifact-cache-cli'
        // Misc
        ARTIFACT_CACHE_CLI_FILENAME = 'develocity-artifact-cache-cli'
        ARTIFACT_CACHE_OPTS = "--npm-home=${ env.HOME }/.npm --reporting-directory=${ env.WORKSPACE }/.develocity/artifact-cache"
    }
    stages {
        stage('Checkout repository') {
            steps {
                checkout scm
            }
        }
        stage('Provision and configure Artifact Cache') {
            steps {
                script {
                    def jdkHome = tool name: 'jdk21', type: 'jdk'
                    def artifactCacheDir = "${ env.HOME }/.jenkins-tools/develocity/${ env.ARTIFACT_CACHE_CLI_VERSION }"
                    def artifactCacheJar = "${ artifactCacheDir }/${ env.ARTIFACT_CACHE_CLI_FILENAME }.jar"
                    withCredentials([usernamePassword(credentialsId: 'artifact-cache-repo', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
                        sh """
                        if [ ! -f "${ artifactCacheJar }" ]; then
                            echo "Downloading Artifact Cache CLI v${ env.ARTIFACT_CACHE_CLI_VERSION }..."
                            mkdir -p "${ artifactCacheDir }"
                            curl --location --fail --silent --show-error \\
                              --connect-timeout 5 --max-time 30 \\
                              --retry 3 --retry-delay 3 --retry-max-time 60 \\
                              -u "\$USER:\$PASS" \\
                              "${ env.ARTIFACT_CACHE_REPO }/com/gradle/${ env.ARTIFACT_CACHE_CLI_FILENAME }/${ env.ARTIFACT_CACHE_CLI_VERSION }/${ env.ARTIFACT_CACHE_CLI_FILENAME }-${ env.ARTIFACT_CACHE_CLI_VERSION }.jar" \\
                              --output "${ artifactCacheJar }"
                        fi
                    """
                    }
                    // Set reusable command variables
                    env.ARTIFACT_CACHE_CMD = "${ jdkHome }/bin/java -jar ${ artifactCacheJar }"
                    def imageName = env.ARTIFACT_CACHE_IMAGE ? "--image-name=${ env.ARTIFACT_CACHE_IMAGE }" : ""
                    env.ARTIFACT_CACHE_CMD_OPTS = "--dv-server=${ env.DV_SERVER } ${ imageName } ${ env.ARTIFACT_CACHE_OPTS }"
                }
            }
        }
        stage('Restore from Artifact Cache') {
            steps {
                script {
                    try {
                        withCredentials([string(credentialsId: 'artifact-cache-access-key', variable: 'DEVELOCITY_ACCESS_KEY')]) {
                            sh """
                                ${ env.ARTIFACT_CACHE_CMD } restore ${ env.ARTIFACT_CACHE_CMD_OPTS }
                            """
                        }
                    } catch (e) {
                        echo "WARNING: Could not restore the Artifact Cache. The build will proceed but may be slower."
                    }
                }
            }
        }
        stage('Build project') {
            steps {
                sh 'npm ci && npm run build'
            }
        }
    }
    post {
        success {
            script {
                try {
                    withCredentials([string(credentialsId: 'artifact-cache-access-key', variable: 'DEVELOCITY_ACCESS_KEY')]) {
                        sh """
                             ${ env.ARTIFACT_CACHE_CMD } store ${ env.ARTIFACT_CACHE_CMD_OPTS }
                        """
                    }
                } catch (e) {
                    echo "WARNING: Failed to store in the Artifact Cache."
                }
            }
        }
        always {
            script {
                // Persist Artifact Cache Logs
                def logPath = ".develocity/artifact-cache/artifact-cache.log"
                if (fileExists(logPath)) {
                    archiveArtifacts artifacts: logPath, allowEmptyArchive: true, fingerprint: false
                }
            }
        }
    }
}
```

<a id="sonar-setup"></a>

### SonarScanner Caching

SonarScanner caching layers on top of your existing project setup. The Artifact Cache CLI auto-detects the SonarScanner user home from `$SONAR_USER_HOME`, falling back to `~/.sonar`. No extra configuration is required as long as the directory exists when `restore` or `store` runs.

> [!TIP]
> Expect image growth of roughly 50 to 100 MB per analyzer version stored.

If the directory is created during build execution, pin it explicitly by appending `--sonar-home` to `ARTIFACT_CACHE_OPTS`:

```groovy
environment {
    ARTIFACT_CACHE_OPTS = "--gradle-home=${ env.HOME }/.gradle --sonar-home=${ env.HOME }/.sonar"
}
```

To opt out of SonarScanner caching even when the user home is present, exclude it from auto-detection:

```groovy
environment {
    ARTIFACT_CACHE_OPTS = "--gradle-home=${ env.HOME }/.gradle --no-autodetect=SONAR"
}
```

<a id="related-documentation"></a>

## Related Documentation

*   [CLI Commands Reference](https://docs.develocity.ai/artifact-cache/1.7/reference/cli-commands/)