Artifactory Gradle Plugin

Introduction

The Artifactory Gradle Plugin deploys your Gradle build artifacts and publishes build information to JFrog Artifactory so you can trace what your build produced.

Who this is for: Gradle application and library developers who configure publishing in the build itself. If your CI already runs JFrog CLI (for example, the Jenkins JFrog Plugin or Setup JFrog CLI on GitHub Actions), see When to use this plugin.

The plugin adds three Gradle tasks.

TaskScopePurpose
artifactoryPublishPer projectCollects deploy details from publications.
extractModuleInfoPer projectProduces moduleInfo.json from collected details.
artifactoryDeployRoot project onlyDeploys artifacts and build information to JFrog Artifactory.

Execution flow: artifactoryPublish then extractModuleInfo then artifactoryDeploy (root).

  • Plugin ID: com.jfrog.artifactory
  • Supported Gradle: The minimum version enforced by code is 6.8.1. Gradle 8 or above is recommended. The plugin is primarily tested with Gradle 9+.
  • Java: The plugin compiles to Java 8. Gradle 9 itself requires Java 17 or later.

When to use this plugin

📘

Recommended path

  • Use this plugin when you want Artifactory publishing configured in your Gradle build (local builds or any CI that runs Gradle with this plugin applied).
  • Prefer JFrog CLI (jf gradle or upload and build-publish commands) when your CI is already CLI-first — for example Jenkins JFrog Plugin or GitHub Actions Setup JFrog CLI.
  • Versions: Gradle 9 or later → plugin 6.x. Gradle 6.8.1 through 8 → plugin 5.x. Do not start new work on plugin 4.x — see Migration and Compatibility.

Prerequisites

Before you configure the plugin, ensure the following:

  • Gradle 6.8.1 or later. If your Gradle version is lower, the build fails with a message that states the minimum supported version.
  • A JDK that satisfies your Gradle version. Gradle 9 requires Java 17 or later.
  • A JFrog Artifactory instance with a Maven or Gradle local repository you can deploy to.
  • Publisher credentials: a username with password, or a username with an access token where your platform allows token authentication. Store secrets in gradle.properties or CI secrets — not in source control.
  • The maven-publish plugin, the ivy-publish plugin, or both, applied to every project you want to publish, and at least one publication defined. The Artifactory plugin collects artifacts from Gradle publications. It doesn't create them.

Quick Start

A working configuration has two parts: a Gradle publication, and the artifactory block that tells the plugin where to deploy it.

The artifactory block requires contextUrl, repository.repoKey, repository.username, and repository.password.

⚠️

Configuring only the artifactory block isn't enough. If no publishing plugin is applied, the build fails with Extension of type 'PublishingExtension' does not exist. Apply maven-publish or ivy-publish and define at least one publication.

Kotlin:

plugins {
    id("java")
    id("maven-publish")
    id("com.jfrog.artifactory") version "6.+"
}

publishing {
    publications {
        create<MavenPublication>("mavenJava") {
            from(components["java"])
        }
    }
}

configure<ArtifactoryPluginConvention> {
    publish {
        contextUrl = "https://acme.jfrog.io/artifactory"
        repository {
            repoKey = "libs-snapshot-local"
            username = project.property("artifactory_user") as String
            password = project.property("artifactory_password") as String
        }
        defaults {
            publications("ALL_PUBLICATIONS")
        }
    }
}

Groovy:

plugins {
    id 'java'
    id 'maven-publish'
    id "com.jfrog.artifactory" version "6.+"
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}

artifactory {
    publish {
        contextUrl = 'https://acme.jfrog.io/artifactory'
        repository {
            repoKey = 'libs-snapshot-local'
            username = "${artifactory_user}"
            password = "${artifactory_password}"
        }
        defaults {
            publications('ALL_PUBLICATIONS')
        }
    }
}

Store artifactory_user and artifactory_password in gradle.properties or supply them as environment variables rather than hardcoding them in the build script.

To deploy, run the following command. Use the Gradle wrapper if your project has one, or a locally installed gradle.

./gradlew artifactoryPublish

The build runs artifactoryPublish, extractModuleInfo, and artifactoryDeploy, then reports the deployed artifacts and the published build information.

> Task :artifactoryPublish
> Task :extractModuleInfo
[pool-1-thread-1] Deploying artifact: https://acme.jfrog.io/artifactory/libs-snapshot-local/org/example/my-app/1.0.0/my-app-1.0.0.jar
[pool-1-thread-1] Deploying artifact: https://acme.jfrog.io/artifactory/libs-snapshot-local/org/example/my-app/1.0.0/my-app-1.0.0.module
[pool-1-thread-1] Deploying artifact: https://acme.jfrog.io/artifactory/libs-snapshot-local/org/example/my-app/1.0.0/my-app-1.0.0.pom
> Task :artifactoryDeploy
Deploying build info...
Build-info successfully deployed.
BUILD SUCCESSFUL
📘

Outside a CI environment the build also prints No build-info config properties file path provided. This line is informational. The plugin reads that file only in CI init-script mode, and build information is still published without it.

Multi-project setup

Apply the plugin with apply false in the root build script, then apply it in allprojects or selected subprojects. The plugin auto-applies itself to the root project when you apply it to a subproject. It isn't applied to buildSrc.

Kotlin:

plugins {
    id("com.jfrog.artifactory") apply false
}

allprojects {
    apply(plugin = "com.jfrog.artifactory")
}

Groovy:

plugins {
    id 'com.jfrog.artifactory' apply false
}

allprojects {
    apply plugin: 'com.jfrog.artifactory'
}

What you should see next

After a successful artifactoryPublish, confirm both the artifacts and the build information.

  1. In the Gradle log, note the deployed artifact URLs and the build name and number (by default, the root project name and an epoch-millisecond timestamp).
  2. In the JFrog Platform UI, open Builds, then open that build name and number to view modules, artifacts, and dependencies.
  3. Optionally verify with JFrog CLI (if configured):
jf rt curl -s -XGET /api/build/<build-name>

For more on reading builds in Artifactory, see Inspect Builds, Manage Builds, and About Build Info.

Configuration Reference

Top-Level artifactory Block

The following table describes the top-level properties you can configure in the artifactory block.

Block or PropertyPurposeDefault
publish { }Publishing configuration.--
buildInfo { }Build information metadata.--
proxy { }HTTP proxy settings.--
clientConfig.timeoutConnection timeout in seconds.--
clientConfig.connectionRetriesNumber of connection retries.--
clientConfig.insecureTlsSkip TLS certificate verification.false
clientConfig.isIncludeEnvVarsInclude environment variables in build information.false
clientConfig.envVarsIncludePatternsComma-separated include patterns for environment variables.--
clientConfig.envVarsExcludePatternsComma-separated exclude patterns for environment variables.--

clientConfig.timeout and clientConfig.connectionRetries have no plugin-level default. When you don't set them, the underlying HTTP client determines the effective value.

Kotlin:

configure<ArtifactoryPluginConvention> {
    publish { /* ... */ }
    buildInfo { /* ... */ }
    proxy { /* ... */ }

    clientConfig.timeout = 600
    clientConfig.connectionRetries = 4
    clientConfig.insecureTls = false
    clientConfig.isIncludeEnvVars = true
    clientConfig.envVarsExcludePatterns = "*password*,*secret*"
    clientConfig.envVarsIncludePatterns = "*not-secret*"
}

Groovy:

artifactory {
    publish { /* ... */ }
    buildInfo { /* ... */ }
    proxy { /* ... */ }

    clientConfig.timeout = 600
    clientConfig.setConnectionRetries(4)
    clientConfig.setInsecureTls(false)
    clientConfig.setIncludeEnvVars(true)
    clientConfig.setEnvVarsExcludePatterns('*password*,*secret*')
    clientConfig.setEnvVarsIncludePatterns('*not-secret*')
}

publish Block

The following table describes the properties available in the publish block.

PropertyPurposeDefault
contextUrlJFrog Artifactory base URL.--
repository { }Target repository settings.--
repository.repoKeySingle repository key.--
repository.releaseRepoKeyRelease repository key.--
repository.snapshotRepoKeySnapshot repository key.--
repository.usernamePublisher username.--
repository.passwordPublisher password.--
repository.ivy { }Ivy layout configuration (when publishIvy = true).--
repository.ivy.ivyLayoutIvy descriptor layout pattern. Setting it enables Ivy publishing.--
repository.ivy.artifactLayoutIvy artifact layout pattern.--
repository.ivy.mavenCompatibleConvert dots to path separators in [organization].true
defaults { }Default configuration applied to all artifactoryPublish tasks.--
publishBuildInfoPublish build information to JFrog Artifactory.true
forkCountNumber of parallel deploy threads.3

Kotlin:

publish {
    contextUrl = "https://acme.jfrog.io/artifactory"
    repository {
        repoKey = "libs-snapshot-local"
        // Or use release and snapshot repositories:
        // releaseRepoKey = "libs-release-local"
        // snapshotRepoKey = "libs-snapshot-local"
        username = project.property("artifactory_user") as String
        password = project.property("artifactory_password") as String
        ivy {
            ivyLayout = "[organization]/[module]/ivy-[revision].xml"
            artifactLayout = "[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]"
            mavenCompatible = true
        }
    }
    defaults {
        publications("mavenJava", "ivyJava")
    }
    publishBuildInfo = true
    forkCount = 5
}

Groovy:

publish {
    contextUrl = 'https://acme.jfrog.io/artifactory'
    repository {
        repoKey = 'libs-snapshot-local'
        username = "${artifactory_user}"
        password = "${artifactory_password}"
        ivy {
            ivyLayout = '[organization]/[module]/ivy-[revision].xml'
            artifactLayout = '[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]'
            mavenCompatible = true
        }
    }
    defaults {
        publications('mavenJava', 'ivyJava')
    }
    publishBuildInfo = true
    forkCount = 5
}

buildInfo Block

The following table describes the properties available in the buildInfo block.

PropertyPurpose
buildNameOverride build name. Default is the root project name.
buildNumberOverride build number. Default is an epoch-millisecond timestamp.
projectJFrog Artifactory project key.
addEnvironmentProperty(key, value)Add a custom environment property.
generatedBuildInfoFilePathPath for an extra build information JSON copy.
deployableArtifactsFilePathPath for deployed artifacts JSON.

Kotlin:

buildInfo {
    buildName = "my-build"
    buildNumber = "" + Random(System.currentTimeMillis()).nextInt(20000)
    project = "project-key"
    addEnvironmentProperty("test.adding.dynVar", Date().toString())
    generatedBuildInfoFilePath = "/path/to/myBuildInfoCopy.json"
    deployableArtifactsFilePath = "/path/to/myArtifactsInBuild.json"
}

Groovy:

buildInfo {
    setBuildName('my-build')
    setBuildNumber('' + new Random(System.currentTimeMillis()).nextInt(20000))
    setProject('project-key')
    addEnvironmentProperty('test.adding.dynVar', new java.util.Date().toString())
    setGeneratedBuildInfoFilePath('/path/to/myBuildInfoCopy.json')
    setDeployableArtifactsFilePath('/path/to/myArtifactsInBuild.json')
}

You can also control build name and number through gradle.properties.

buildInfo.build.name=my-super-cool-build
buildInfo.build.number=r9001

proxy Block

The following table describes the properties available in the proxy block.

PropertyPurpose
hostProxy hostname.
portProxy port.
usernameProxy username.
passwordProxy password.
noProxyHosts to bypass the proxy.
proxy {
    host = 'www.somehost.org'
    port = 8080
    username = 'userid'
    password = 'password'
    noProxy = 'internal.myorg.com'
}

For dependency resolution through a proxy, use the standard Gradle proxy configuration in gradle.properties.

systemProp.http.proxyHost=www.somehost.org
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=userid
systemProp.http.proxyPassword=password

artifactoryPublish Task and defaults Block

The defaults block inside publish applies configuration to every artifactoryPublish task. You can also configure a specific project's task directly.

The following table describes the properties available on the task or in the defaults block.

PropertyPurposeDefault
publications(...)Publications to include.--
publications("ALL_PUBLICATIONS")Include all known publications.--
propertiesMap of artifact properties.--
properties { configName artifactSpec, key:val }Scoped properties (Groovy closure).--
skipSkip this project entirely.false
publishArtifactsPublish artifacts.true
publishPomPublish POM files.true
publishIvyPublish Ivy descriptors.true
moduleTypeModule type in build information.GRADLE

The following moduleType values are valid: GENERIC, MAVEN, GRADLE, IVY, DOCKER, NUGET, NPM, GO, PYPI, CPP, and BUILD.

When a CI server supplies publisher configuration through a build-info.properties file, that configuration takes precedence over publishPom and publishIvy values set in the build script.

Kotlin (per-project task):

tasks.named<ArtifactoryTask>("artifactoryPublish") {
    publications(
        publishing.publications["ivyJava"],
        "mavenJava",
        "ALL_PUBLICATIONS"
    )
    setProperties(mapOf("key1" to "value1", "key2" to "value2"))
    skip = false
    setPublishArtifacts(true)
    setPublishPom(true)
    setPublishIvy(true)
    setModuleType("GRADLE")
}

Groovy (per-project task):

artifactoryPublish {
    publications('ALL_PUBLICATIONS')
    properties = ['qa.level': 'basic', 'dev.team': 'core']
    properties {
        simpleFile '**:**:**:*@*', simpleFile: 'only on settings file'
    }
    skip = false
    publishArtifacts = true
    publishPom = true
    publishIvy = true
    moduleType = 'GRADLE'
}

Artifact notation for scoped properties: group:module:version:classifier@type (for example, org.example:my-artifact:1.0.0:test@jar). Wildcards: * for any characters, ? for a single character. Use all as the configuration name to apply to all publications or configurations.

Publications

ALL_PUBLICATIONS

Set publications("ALL_PUBLICATIONS") to publish artifacts from every publication defined in the project.

Default Publications

When you don't specify any publications and the project has the publishing extension applied, the plugin automatically looks for mavenJava, mavenJavaPlatform, mavenWeb, and ivyJava.

Maven and Ivy Side by Side

The following example shows how to configure both Maven and Ivy publications in the same project.

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
        ivyJava(IvyPublication) {
            from components.java
        }
    }
}

artifactory {
    publish {
        defaults {
            publications('mavenJava', 'ivyJava')
        }
    }
}

Artifact Properties

Simple Map

artifactoryPublish {
    properties = ['qa.level': 'basic', 'q.os': 'win32, deb, osx']
}

Scoped Properties (Groovy Closure)

artifactoryPublish {
    properties {
        foo '*:*:*:*@*', platform: 'linux', 'win64'
        mavenJava 'org.jfrog:*:*:*@*', key1: 'val1'
        all 'org.jfrog:shared:1.?:*@*', key2: 'val2', key3: 'val3'
    }
}

The syntax follows this format: configName 'group:module:version:classifier@type', key1:'value1', key2:'value2'

  • configName: A publication name, or all to apply to all publications.
  • The artifact filter supports * (any characters) and ? (single character).

Use Cases and Examples

The plugin repository includes sample projects that the plugin's own functional tests build. Use them as reference configurations.

Use CaseExample ProjectNotes
Multi-module Maven + Ivy (Groovy)gradle-example-publishUses mavenJava and ivyJava publications.
Multi-module (Kotlin DSL)gradle-kts-example-publishSame configuration in Kotlin.
Android (APK and AAR)gradle-android-exampleCustom publications per module, and per-project publications(...).
Proxy with noProxy bypassgradle-example-publish/build.gradleUses proxy { host, port, noProxy }.
Default BOMgradle-example-default-bomJava Platform (BOM) publishing.
Custom BOMgradle-example-custom-bomCustom mavenJavaPlatform.
Version cataloggradle-example-version-catalogProducer and consumer setup.
Gradle plugin publishinggradle-pluginUses ALL_PUBLICATIONS.
Skip root or specific modulesAll examplesUses artifactoryPublish.skip = true.

For end-to-end sample projects, see the Gradle examples in the JFrog project-examples repository.

Sub-Project Control

The plugin supports hierarchical configuration. Define artifactory { } in the root project and all subprojects inherit it. Any subproject can override the publish or repository configuration.

Set artifactoryPublish.skip = true on a project to exclude it from publishing.

./gradlew clean api:artifactoryPublish shared:artifactoryPublish

CI Integration

If your CI server already installs and configures JFrog CLI — for example the Jenkins JFrog Plugin or Setup JFrog CLI on GitHub Actions — you can publish with CLI commands and may not need this Gradle plugin in the build script.

When CI runs Gradle with this plugin, a CI driver (JFrog CLI or a legacy Jenkins Artifactory Plugin job) may apply the plugin through an init script (initscripttemplate.gradle). That init script does the following:

  • Applies ArtifactoryPluginSettings to the settings, which adds JFrog Artifactory as a resolution repository.
  • Applies ArtifactoryPlugin to all projects.
  • Sets setCiServerBuild() on every artifactoryPublish task to enable CI mode.

In CI mode, publications are read from the ArtifactoryClientConfiguration.publisher.publications property, which is populated from build-info.properties generated by JFrog CLI or the CI integration.

Resolver from Properties

When a build-info.properties file is present (set through the BUILDINFO_PROPFILE or PROP_PROPS_FILE environment variable), the plugin reads contextUrl and repoKey from it and configures JFrog Artifactory as the resolution repository, replacing other remote Maven and Ivy repositories.

Migration and Compatibility

Version 6 (Current)

Version 6 of the Gradle Artifactory Plugin introduces support for Gradle version 9. The code and documentation for Version 6 are available at the Gradle Artifactory Plugin GitHub repository.

Note: For Gradle version 6.8.1 through 8 (inclusive), use version 5. For Gradle 9, use version 6.

Version 6 includes the following breaking changes:

  • The plugin compiles to Java 8. Gradle 9 itself requires Java 17 or later.
  • The minimum Gradle version enforced by the plugin is 6.8.1. Gradle 8 or above is recommended. The plugin is primarily tested with Gradle 9+.
  • The web-archive convention attribute has been removed. The plugin now produces both JAR and WAR archives.

Version 5

This major release completely rewrote the plugin code from Groovy to Java.

Version 5 includes the following breaking changes:

  • The minimum supported Gradle version has been increased to 6.8.1. The legacy archive configurations are no longer supported.
  • The parent closure in the artifactory convention is no longer compatible or supported.

Migrate from Version 4 to Version 5 or 6

The following Version 4 features have been removed or relocated.

Version 4 FeatureStatus in Version 5 and 6
publishConfigs()Removed. Use publications() instead.
mavenDescriptorRemoved.
ivyDescriptorRemoved.
publishBuildInfo in defaultsMoved to publish { publishBuildInfo = ... }.
contextUrl on artifactoryPublish taskRemoved from task. Set on publish { contextUrl = ... }.
clientConfig.publisher.* on taskRemoved from task. Set on artifactory { publish { repository { ... } } }.
clientConfig.proxy.*Replaced with proxy { } closure.
clientConfig.info.*Replaced with buildInfo { } closure.
parent closureRemoved.

Troubleshooting

The following table describes common problems and their solutions.

ProblemSolution
Build fails with Extension of type 'PublishingExtension' does not exist.Apply the maven-publish plugin, the ivy-publish plugin, or both, and define at least one publication. The Artifactory plugin collects artifacts from Gradle publications and doesn't create them.
Build fails with a Gradle version error.The plugin requires Gradle 6.8.1 or later. Update Gradle or use an older plugin version. The error message includes the minimum supported version.
Deploy fails with 401 or 403.Confirm the user or token can deploy to the target repository and publish build information. Store credentials in gradle.properties or CI secrets — not in source control. An access token can be used as the password where your platform allows it.
Artifacts deploy but you can't find the build under your Artifactory Project.Set buildInfo { project = "your-project-key" } (or the matching property) and confirm the Project exists.
Wrong repository or empty deploy.Use a Maven or Gradle local repository key. Match snapshot versus release repositories (repoKey versus releaseRepoKey / snapshotRepoKey) to your version scheme.
Build log shows success but you don't know where to look.Open Builds in the JFrog Platform UI and open the build name printed in the log, or run jf rt curl -s -XGET /api/build/<build-name> with a configured CLI.
No artifacts published.Verify that publications() is configured and the named publications exist in the project.
The build prints No build-info config properties file path provided.This message is informational. The plugin looks for a CI-supplied build-info.properties file and continues without it. Build information is still published.
Invalid properties specification error.Use the format configName 'group:module:version:classifier@type', key1:'value1', key2:'value2'.
You need detailed logs.Run Gradle with -d for debug output.
Proxy doesn't work for deployment.Configure the proxy { } block inside artifactory { }.
Proxy doesn't work for resolution.Proxy for dependency resolution uses the standard Gradle configuration in gradle.properties (systemProp.http.proxyHost and related properties). The plugin doesn't intervene in resolution.

Related topics

Legacy: Gradle Artifactory Plugin Version 4

Do not start new projects on Version 4. Migrate to Version 5 or 6 using the table in Migrate from Version 4 to Version 5 or 6.

Version 4 used a different Convention DSL (publishConfigs, task-level contextUrl, clientConfig.publisher.*, and related APIs). Those features are removed or relocated in Version 5 and 6. For historical Version 4 examples, see older tags in the artifactory-gradle-plugin repository and the migrate table above.


Did this page help you?