Skip to content

Using Maven and Gradle with RepoForge.io ​

RepoForge.io hosts Maven repositories in the standard Maven layout, so mvn deploy and Gradle's maven-publish plugin can publish to them, and any Maven or Gradle build can resolve from them. This page covers publishing, resolving, using tokens in CI, and publishing SDKs outside Maven Central.

Your repository URL ​

Every RepoForge.io account has one Maven repository:

https://api.repoforge.io/maven/unique-hash-id/

Replace unique-hash-id with your organization's unique ID. The Maven page of the dashboard shows the URL with your ID filled in, and the Publish artifact button shows the configuration below for your account.

Artifacts are identified by their groupId and artifactId, as on any Maven repository. You don't need to create anything in the dashboard first: an artifact appears the first time you publish it.

Access tokens ​

Maven and Gradle authenticate with HTTP basic auth. Use an access token as the password, with any username (the examples use __token__):

  • To publish, the token needs the Maven - Full access role.
  • To resolve private artifacts, the token needs the Maven - Read only role (or Full access).

Create tokens under Access Tokens in the dashboard. You can use your RepoForge.io email address and password instead, but tokens are better for builds and CI because you can revoke them individually.

Publishing with Maven ​

Step 1: Add your token to settings.xml ​

Add a server entry to ~/.m2/settings.xml. The id is how Maven matches the credentials to the repository in your pom.xml:

xml
<settings>
  <servers>
    <server>
      <id>repoforge</id>
      <username>__token__</username>
      <password>${env.REPOFORGE_TOKEN}</password>
    </server>
  </servers>
</settings>

Maven reads ${env.REPOFORGE_TOKEN} from the environment, so the token doesn't need to be written to the file.

Step 2: Add the repository to your pom.xml ​

xml
<distributionManagement>
  <repository>
    <id>repoforge</id>
    <url>https://api.repoforge.io/maven/unique-hash-id/</url>
  </repository>
</distributionManagement>

Step 3: Deploy ​

bash
export REPOFORGE_TOKEN=your-access-token
mvn deploy

Maven uploads the jar, the POM and any other attached artifacts, such as sources, Javadoc and .asc signatures.

Publishing with Gradle ​

Step 1: Add your token to gradle.properties ​

Add your credentials to ~/.gradle/gradle.properties, outside your project:

properties
repoforgeUsername=__token__
repoforgePassword=your-access-token

Gradle reads these for a repository named repoforge when it uses credentials(PasswordCredentials::class).

Step 2: Configure publishing ​

kotlin
plugins {
    `java-library`
    `maven-publish`
}

group = "com.example"
version = "1.0.0"

publishing {
    publications {
        create<MavenPublication>("maven") {
            from(components["java"])
        }
    }
    repositories {
        maven {
            name = "repoforge"
            url = uri("https://api.repoforge.io/maven/unique-hash-id/")
            credentials(PasswordCredentials::class)
        }
    }
}
groovy
plugins {
    id 'java-library'
    id 'maven-publish'
}

group = 'com.example'
version = '1.0.0'

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
        }
    }
    repositories {
        maven {
            name = 'repoforge'
            url = uri('https://api.repoforge.io/maven/unique-hash-id/')
            credentials(PasswordCredentials)
        }
    }
}

Step 3: Publish ​

bash
./gradlew publish

Gradle publishes the jar, the POM and its .module metadata file.

Resolving artifacts ​

With Maven ​

Add the repository and the dependency to the consuming project's pom.xml. For private artifacts, add a repoforge server entry to settings.xml as in step 1 above, using a read-only token.

xml
<repositories>
  <repository>
    <id>repoforge</id>
    <url>https://api.repoforge.io/maven/unique-hash-id/</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>com.example</groupId>
    <artifactId>my-sdk</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

With Gradle ​

kotlin
repositories {
    mavenCentral()
    maven {
        name = "repoforge"
        url = uri("https://api.repoforge.io/maven/unique-hash-id/")
        credentials(PasswordCredentials::class)
    }
}

dependencies {
    implementation("com.example:my-sdk:1.0.0")
}
groovy
repositories {
    mavenCentral()
    maven {
        name = 'repoforge'
        url = uri('https://api.repoforge.io/maven/unique-hash-id/')
        credentials(PasswordCredentials)
    }
}

dependencies {
    implementation 'com.example:my-sdk:1.0.0'
}

For a public artifact, leave out the credentials line in Gradle and the server entry in Maven.

SNAPSHOT versions ​

SNAPSHOT versions such as 1.0-SNAPSHOT, the default for new Maven projects, work like any other version. Each mvn deploy or ./gradlew publish adds a timestamped build, for example my-sdk-1.0-20261025.223325-1.jar, and builds that depend on 1.0-SNAPSHOT resolve the newest one. RepoForge.io keeps the 10 newest builds of each SNAPSHOT version and deletes older ones.

Public and private artifacts ​

Each artifact is either public or private:

  • Public artifacts can be resolved by anyone, without credentials. Publishing always needs a token.
  • Private artifacts can only be resolved with credentials that have a Maven role.

Free accounts can only publish public artifacts. On paid plans, artifacts are private by default, and you can make an artifact public with the Private switch on the Maven page of the dashboard, or with the REST API. Artifacts can also use package level permissions to limit access to specific users and tokens.

Publishing from GitHub Actions ​

Store your access token as a repository secret named REPOFORGE_TOKEN.

With Maven, actions/setup-java writes the settings.xml server entry for you. server-username and server-password are the names of environment variables, not the values:

yaml
name: Publish to RepoForge.io

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '21'
          server-id: repoforge
          server-username: REPOFORGE_USERNAME
          server-password: REPOFORGE_TOKEN
      - run: mvn -B deploy
        env:
          REPOFORGE_USERNAME: __token__
          REPOFORGE_TOKEN: ${{ secrets.REPOFORGE_TOKEN }}

With Gradle, pass the credentials as ORG_GRADLE_PROJECT_ environment variables, which Gradle reads as the repoforgeUsername and repoforgePassword properties:

yaml
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '21'
      - uses: gradle/actions/setup-gradle@v4
      - run: ./gradlew publish
        env:
          ORG_GRADLE_PROJECT_repoforgeUsername: __token__
          ORG_GRADLE_PROJECT_repoforgePassword: ${{ secrets.REPOFORGE_TOKEN }}

Publishing commercial SDKs outside Maven Central ​

Since October 1, 2026, Sonatype requires its paid Publisher Pro tier for artifacts of a commercial nature published to Maven Central, such as SDKs, generated API clients, drivers and agents. Free publishers also have monthly limits on releases, files and storage. See Sonatype's commercial use notice and publishing limits for the current terms.

If you publish an SDK to RepoForge.io instead, keep the following in mind:

  • Make the artifact public so that your customers can resolve it without an account or token.
  • Your customers need to add your repository to their builds, as shown in Resolving artifacts. Maven and Gradle only look in Maven Central by default, so put the repository snippet in your SDK's installation instructions.
  • Your artifact won't appear in Maven Central search. Link to your installation instructions from your own documentation instead.
  • Keep your coordinates. You can publish under the same groupId you use today, so existing customers only need to add the repository, not change their dependency.
  • GitHub Packages isn't an alternative for public SDKs. Its Maven registry needs authentication even to read packages, so every customer would need a GitHub token.

Limitations ​

  • Re-publishing a release replaces its files. Publishing a file that already exists overwrites it. Bump the version for every release so that builds that cached the old file stay consistent.
  • RepoForge.io generates maven-metadata.xml and checksums. Copies uploaded by Maven or Gradle are checked or ignored, so the metadata always lists exactly the versions that are stored.

Troubleshooting ​

  • 401 Unauthorized – Check that the <id> in settings.xml matches the repository <id> in pom.xml, or that the Gradle repository is named repoforge to match the property names.
  • 403 Forbidden – The token doesn't have the right Maven role. Publishing needs Maven - Full access.
  • 400 Bad Request – The file name doesn't match the artifact and version directory it's uploaded to.
  • 413 Payload Too Large – Your account has run out of storage. See Account and billing.

Built with care by the RepoForge.io team.