Maven packages in Artifact Registry

  • Tier: Premium, Ultimate
  • Offering: GitLab.com
  • Status: Beta

Use the Maven repository to store Maven packages.

Supported clients

  • mvn
  • gradle, with either a Groovy or a Kotlin build script
  • sbt

Authenticate

All three clients authenticate with basic authentication. Custom header authentication is not supported, so the Private-Token header used by the older GitLab Maven package registry does not work.

Prerequisites:

  • The GitLab CLI, version 1.115.0 or later.

The GitLab CLI uses the GITLAB_TOKEN environment variable if it is set. Otherwise, it uses the credential that glab auth login stores. To check that the GitLab CLI can authenticate, run:

shell
glab auth status

If the command does not report that you are logged in, authenticate with the GitLab CLI:

shell
glab auth login

Then follow the steps for your preferred client.

Run the following command:

shell
glab artifact-registry login --maven --registry <repository_url> --registry-alias <alias>

This writes a <server> block in ~/.m2/settings.xml, keyed by the alias you choose. In your pom.xml, the <repository> element’s <id> must match this alias.

Run the following command:

shell
glab artifact-registry login --gradle --registry <repository_url> --registry-alias <alias>

This writes <alias>Url, <alias>Username, and <alias>Password in ~/.gradle/gradle.properties. Pick an alias that is a valid identifier. The default alias comes from the host name and contains hyphens, which a Groovy build script cannot use in ${...} references.

Run the following command:

shell
glab artifact-registry login --sbt --registry <repository_url>

This writes a credentials += line in ~/.sbt/1.0/credentials.sbt. Only a stock sbt version 1.x installation reads this file. An sbt that moved its global base with -Dsbt.global.base does not read this file.

Run the glab artifact-registry login command again for your client before the token expires. The token lasts 15 minutes by default, and up to 12 hours if you request a longer duration.

Configure your client

A Maven repository is available at:

https://<registry_host>/<registry_handle>/maven/<repository_name>

Replace the following placeholders:

  • <registry_host>: Enter the hostname from your repository’s setup instructions. To find it, go to your repository and select More actions > View setup instructions.
  • <registry_handle>: Enter your organization’s registry handle.
  • <repository_name>: Enter the name of your repository.

The GitLab CLI (glab) writes the credential for you. It requires glab 1.115.0 or later. The artifact-registry login commands are experiments, so their names and flags can change.

Use a remote or virtual repository in place of Maven Central

Use a remote or virtual repository in place of Maven Central so that your build resolves its dependencies through artifact registry.

Prerequisites:

  • One of the following:
    • A remote Maven repository that proxies Maven Central.
    • A virtual Maven repository with a remote repository that proxies Maven Central as one of its upstreams.
  • An authenticated Maven client.

With this configuration, your build no longer contacts Maven Central directly.

In a virtual repository, list the Maven Central remote repository as the last upstream. A virtual repository serves each file from the first upstream that has it, so your other upstreams take precedence over a package with the same name on Maven Central.

In the following examples:

  • <repository_url>: The repository URL from Configure your client. For example, https://ar.example.com/acme/maven/my-repo.
  • <alias>: For mvn and gradle, the alias you passed to --registry-alias when you authenticated.

To use the repository in place of Maven Central:

  1. Merge the following mirror into your ~/.m2/settings.xml file:

    xml
    <mirrors>
      <mirror>
        <id><alias></id>
        <url><repository_url></url>
        <mirrorOf>central</mirrorOf>
      </mirror>
    </mirrors>

    The mirror <id> must match the ID of the <server> block that glab wrote, so use the same alias.

  2. Optional. To also resolve snapshot dependencies, merge the following repository into your pom.xml file:

    xml
    <repositories>
      <repository>
        <id><alias></id>
        <url><repository_url></url>
        <snapshots>
          <enabled>true</enabled>
        </snapshots>
      </repository>
    </repositories>

To use the repository in place of Maven Central:

  • Replace mavenCentral() with the following repository block, which reads values that glab wrote to gradle.properties:

    • In Groovy DSL, in build.gradle:

      groovy
      maven {
        url = providers.gradleProperty('<alias>Url').get()
        credentials {
          username = providers.gradleProperty('<alias>Username').get()
          password = providers.gradleProperty('<alias>Password').get()
        }
      }
    • In Kotlin DSL, in build.gradle.kts:

      kotlin
      maven {
        url = uri(providers.gradleProperty("<alias>Url").get())
        credentials {
          username = providers.gradleProperty("<alias>Username").get()
          password = providers.gradleProperty("<alias>Password").get()
        }
      }

To use the repository in place of Maven Central:

  • In your build.sbt file, set externalResolvers:

    scala
    externalResolvers := Resolver.combineDefaultResolvers(
      resolvers.value.toVector :+ ("artifact-registry" at "<repository_url>"),
      mavenCentral = false
    )

    This setting keeps your project resolvers and the local Ivy repository, and removes the default Maven Central resolver.

Dependencies your build would fetch from Maven Central now resolve through the repository.

Republishing a version

  • Artifact Registry accepts a re-upload when the content is byte-for-byte identical.
  • It returns 409 after the content differs. A rebuilt Java Archive (JAR) usually differs, so a repeated deploy of the same version usually fails.
  • Use a new version number instead.

Limits

Limit Value
Artifact size 5 GB
maven-metadata.xml size 10 MB
Versions per package 25,000

For the full list of limits, see Artifact Registry limits.

Delete a Maven package

The Management API deletes Maven packages, versions, and files, one at a time or in a batch. Maven itself has no delete command.

For specific steps, see the Artifact Registry API.

Virtual repositories

A virtual Maven repository reads from its upstream repositories in the order you list them.

  • The first upstream that holds an artifact or a version-level metadata file serves it.
  • The registry merges a package-level maven-metadata.xml from the upstreams that hold one, so the document lists the union of their versions.
  • A merged package-level maven-metadata.xml response carries X-Checksum-Sha1, so Maven verifies the document without requesting its .sha1 sidecar.
  • The registry computes a checksum sidecar (.sha1, .md5, .sha256, .sha512) from the bytes it serves for the file it describes. The registry never requests a sidecar from an upstream.
  • The registry does not serve an .md5 sidecar while FIPS mode is enabled.
  • You cannot publish to a virtual Maven repository.

For details, see Artifact Registry repositories.

Errors you might see

Error What it means
Release file already exists with different content. You re-deployed a version with changed content. Use a new version number.
Per-package version cap reached. The package holds the maximum number of versions.
Request body exceeds the configured maximum. The upload is larger than 5 GB.
Uploaded checksum does not match the stored parent file. The checksum file does not match the artifact it describes. Re-run the deploy.
MD5 checksum sidecars are not served while FIPS mode is enabled. The instance runs in Federal Information Processing Standards (FIPS) mode, which does not serve Message Digest 5 (MD5) checksums.

A mismatched alias makes Maven send no credentials at all. The deploy fails with 401, without saying why.