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:
<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
<distributionManagement>
<repository>
<id>repoforge</id>
<url>https://api.repoforge.io/maven/unique-hash-id/</url>
</repository>
</distributionManagement>Step 3: Deploy
export REPOFORGE_TOKEN=your-access-token
mvn deployMaven 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:
repoforgeUsername=__token__
repoforgePassword=your-access-tokenGradle reads these for a repository named repoforge when it uses credentials(PasswordCredentials::class).
Step 2: Configure publishing
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)
}
}
}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
./gradlew publishGradle 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.
<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
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")
}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:
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:
- 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
groupIdyou 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.xmland 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>insettings.xmlmatches the repository<id>inpom.xml, or that the Gradle repository is namedrepoforgeto 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.