Skip to main content

Prerequisites

Before you begin, ensure you have:

Java 17+

MCReleaser requires Java 17 or higher

Built Artifact

A compiled JAR file ready for distribution

Platform Accounts

Accounts on the platforms where you want to publish

API Tokens

API tokens/keys for each target platform

Step-by-Step Guide

1

Download MCReleaser

Download the latest mcreleaser.jar from the GitHub Releases page.
# Example: download to your project directory
curl -L -o mcreleaser.jar https://github.com/HSGamer/MCReleaser/releases/latest/download/mcreleaser.jar
2

Prepare Your Artifact

Build your Minecraft project to generate the JAR file.
# For Maven projects
mvn clean package

# For Gradle projects
./gradlew build
Your artifact will typically be in:
  • Maven: target/your-plugin-1.0.0.jar
  • Gradle: build/libs/your-plugin-1.0.0.jar
3

Set Up API Tokens

Obtain API tokens from your target platforms. Store them securely as environment variables.
export MODRINTH_TOKEN="your-modrinth-token"
export HANGAR_KEY="your-hangar-api-key"
export GITHUB_TOKEN="your-github-token"
Never hardcode tokens in your command or commit them to version control!
4

Run Your First Release

Execute MCReleaser with the required properties. Here’s a complete example:
java \
    -Dname="AwesomePlugin" \
    -Dversion="1.0.0" \
    -Ddescription="A plugin that makes Minecraft more awesome" \
    -DgameVersions="1.20,1.20.1,1.20.2,1.20.4" \
    -Dfiles="build/libs/*.jar" \
    -Dplatforms="modrinth,hangar" \
    -DmodrinthToken="$MODRINTH_TOKEN" \
    -DmodrinthProject="awesome-plugin" \
    -DmodrinthLoaders="paper,spigot" \
    -DhangarKey="$HANGAR_KEY" \
    -DhangarProject="AwesomePlugin" \
    -DhangarChannel="Release" \
    -jar mcreleaser.jar
The -D flag sets Java system properties. Environment variables use UPPER_SNAKE_CASE, but properties use camelCase (e.g., MODRINTH_TOKEN becomes -DmodrinthToken).
5

Verify the Upload

MCReleaser will output logs showing the progress of each platform upload:
[INFO] Starting upload to Modrinth...
[INFO] Modrinth upload successful: https://modrinth.com/plugin/awesome-plugin/version/1.0.0
[INFO] Starting upload to Hangar...
[INFO] Hangar upload successful: https://hangar.papermc.io/YourUser/AwesomePlugin/versions/1.0.0
Visit the provided URLs to confirm your releases are live.

Example: Publishing to GitHub Releases

Here’s a practical example of publishing to GitHub Releases:
java \
    -Dname="MyMinecraftMod" \
    -Dversion="2.1.0" \
    -Ddescription="Adds new biomes and structures to Minecraft" \
    -DgameVersions="1.20.4,1.20.6" \
    -Dfiles="build/libs/MyMod-2.1.0.jar" \
    -Dplatforms="github" \
    -DgithubToken="$GITHUB_TOKEN" \
    -DgithubRepository="YourUsername/MyMinecraftMod" \
    -DgithubRef="refs/tags/v2.1.0" \
    -jar mcreleaser.jar
  • name: Display name of your artifact
  • version: Semantic version (e.g., 1.0.0, 2.1.0)
  • description: Short description of this release
  • gameVersions: Comma-separated list of supported Minecraft versions
  • files: Glob pattern matching files to upload
  • platforms: Comma-separated list of target platforms (or “all”)
  • githubRepository: Format is owner/repo
  • githubRef: Git reference, typically a tag like refs/tags/v1.0.0

Property Naming Convention

MCReleaser uses a specific naming convention for properties:
java \
    -DmodrinthToken="token" \
    -DgameVersions="1.20" \
    -DcurseforgeProject="12345" \
    -jar mcreleaser.jar
CLI: Use -D prefix with camelCase (e.g., -DmodrinthToken)Docker: Use -e with UPPER_SNAKE_CASE (e.g., MODRINTH_TOKEN)

Advanced: Publishing to All Platforms

To publish to all supported platforms simultaneously:
java \
    -Dname="UniversalPlugin" \
    -Dversion="3.0.0" \
    -Ddescription="A cross-platform Minecraft plugin" \
    -DgameVersions="1.20,1.20.1,1.20.2,1.20.4,1.20.6" \
    -Dfiles="target/UniversalPlugin-3.0.0.jar" \
    -Dplatforms="all" \
    -DgithubToken="$GITHUB_TOKEN" \
    -DgithubRepository="user/repo" \
    -DgithubRef="refs/tags/v3.0.0" \
    -DmodrinthToken="$MODRINTH_TOKEN" \
    -DmodrinthProject="universal-plugin" \
    -DmodrinthLoaders="paper,spigot,bukkit" \
    -DhangarKey="$HANGAR_KEY" \
    -DhangarProject="UniversalPlugin" \
    -DhangarChannel="Release" \
    -DpolymartKey="$POLYMART_KEY" \
    -DpolymartResource="12345" \
    -DcurseforgeToken="$CURSEFORGE_TOKEN" \
    -DcurseforgeProject="67890" \
    -jar mcreleaser.jar
When using -Dplatforms="all", ensure you’ve set up credentials for all platforms, or set -DannounceMissingKey=true to see which credentials are missing.

Sync vs Async Execution

By default, MCReleaser uploads to platforms concurrently (async) for faster execution. You can control this behavior:
# Uploads to all platforms simultaneously
java -Dplatforms="modrinth,hangar,github" \
     -Dsync=false \
     # ... other properties
     -jar mcreleaser.jar
// From CLIExecutor.java:18-19
boolean runSync = CLIPropertyKey.SYNC.asBoolean(false);
BundlePlatform bundlePlatform = new BundlePlatform(platforms, runSync);

File Selection

MCReleaser uses glob patterns to select files for upload:
# Single file
-Dfiles="target/plugin-1.0.0.jar"

# All JARs in a directory
-Dfiles="build/libs/*.jar"

# Multiple patterns (space-separated)
-Dfiles="build/libs/*.jar docs/*.pdf"
The first matched file becomes the primary artifact, and additional files are treated as secondary files.
// From CLIExecutor.java:37-41
private static FileBundle getFileBundle() {
    String fileGlobs = CLIPropertyKey.FILES.getValue();
    Validate.check(fileGlobs != null, "File globs not found");
    return PathUtil.getFileBundle(Paths.get("."), StringUtil.splitSpace(fileGlobs));
}

Troubleshooting

Enable property validation to see which properties are missing:
java -DannounceMissingKey=true -jar mcreleaser.jar
This will print all missing required properties for your selected platforms.
This occurs when:
  1. No platforms are specified (missing -Dplatforms)
  2. Platform names are misspelled
  3. Required credentials for all specified platforms are missing
Valid platform names: github, modrinth, hangar, polymart, curseforge
Check your -Dfiles glob pattern:
# Wrong (relative to JAR location)
-Dfiles="../build/libs/*.jar"

# Correct (relative to working directory)
-Dfiles="build/libs/*.jar"
MCReleaser looks for files relative to the current working directory (where you run the command).
Verify your tokens are correctly set:
# Check if environment variable is set
echo $MODRINTH_TOKEN

# Ensure proper camelCase conversion
-DmodrinthToken="$MODRINTH_TOKEN"  # Correct
-Dmodrinth_token="$MODRINTH_TOKEN"  # Wrong

Next Steps

Platform Configuration

Learn detailed configuration for each platform

Docker Usage

Run MCReleaser in a containerized environment

GitHub Actions

Automate releases with CI/CD

Environment Variables

Complete reference of all available properties

Build docs developers (and LLMs) love