The GithubPlatform class implements the Platform interface to upload artifacts to GitHub Releases using the GitHub API.
Package
me.hsgamer.mcreleaser.github.GithubPlatform
Class Declaration
public class GithubPlatform implements Platform {
private final Logger logger = LoggerFactory.getLogger(getClass());
}
Constructor
Creates a new GitHub platform instance and automatically sets version and name from Git ref if available.
public GithubPlatform() {
if (GithubPropertyKey.REF.isPresent()) {
String version = getVersionFromRef(GithubPropertyKey.REF.getValue());
if (CommonPropertyKey.VERSION.isAbsent()) {
CommonPropertyKey.VERSION.setValue(version);
}
if (CommonPropertyKey.NAME.isAbsent()) {
CommonPropertyKey.NAME.setValue(version);
}
}
}
Automatic Version Extraction:
- Extracts version from Git ref (e.g.,
refs/tags/v1.0.0 → v1.0.0)
- Sets
VERSION and NAME if not already configured
Methods
createUploadRunnable
Creates a batch runnable that uploads files to a GitHub Release.
The bundle of files to upload as release assets
Returns a BatchRunnable if all required properties are present, otherwise empty
@Override
public Optional<BatchRunnable> createUploadRunnable(FileBundle fileBundle) {
if (PropertyKeyUtil.isAbsentAndAnnounce(logger,
GithubPropertyKey.TOKEN,
GithubPropertyKey.REPOSITORY,
GithubPropertyKey.REF)) {
return Optional.empty();
}
// Create upload tasks...
}
Upload Process
The upload is executed in three phases:
Phase 0: Preparation
-
Create GitHub Instance
GitHub gitHub = new GitHubBuilder()
.withOAuthToken(GithubPropertyKey.TOKEN.getValue())
.build();
-
Get Repository
GHRepository repository = gitHub.getRepository(
GithubPropertyKey.REPOSITORY.getValue()
);
Phase 1: Release Creation
Creates or retrieves the GitHub Release:
GHRelease release = repository.getReleaseByTagName(
GithubPropertyKey.REF.getValue()
);
if (release == null) {
release = repository.createRelease(GithubPropertyKey.REF.getValue())
.draft(GithubPropertyKey.DRAFT.asBoolean(false))
.prerelease(GithubPropertyKey.PRERELEASE.asBoolean(false))
.name(CommonPropertyKey.NAME.getValue())
.body(CommonPropertyKey.DESCRIPTION.getValue())
.create();
}
Phase 2: File Upload
Uploads all files from the bundle:
for (File file : fileBundle.allFiles()) {
release.uploadAsset(file, "application/octet-stream");
logger.info("File uploaded: {}", file.getName());
}
logger.info("Release URL: {}", release.getHtmlUrl());
Required Properties
GitHub personal access token or OAuth token with repo scope
Repository in format owner/repo (e.g., user/my-plugin)
Git reference for the release (e.g., refs/tags/v1.0.0 or v1.0.0)
Optional Properties
Create release as draft (not published)
Mark release as pre-release
Common Properties
These properties are shared across platforms:
Release name/title (auto-set from ref if not provided)
Version number (auto-set from ref if not provided)
Release description/changelog (supports Markdown)
Configuration Examples
Basic Release
export GITHUB_TOKEN="ghp_1234567890abcdef"
export GITHUB_REPOSITORY="user/my-plugin"
export GITHUB_REF="refs/tags/v1.0.0"
export DESCRIPTION="Initial release"
java -jar mcreleaser-cli.jar
Draft Release
export GITHUB_TOKEN="ghp_..."
export GITHUB_REPOSITORY="user/my-plugin"
export GITHUB_REF="v2.0.0-beta"
export GITHUB_DRAFT="true"
export GITHUB_PRERELEASE="true"
export NAME="My Plugin v2.0.0-beta"
export DESCRIPTION="Beta release for testing"
GitHub Actions Integration
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: ./gradlew build
- name: Release to GitHub
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REF: ${{ github.ref }}
DESCRIPTION: ${{ github.event.head_commit.message }}
FILES: "build/libs/*.jar"
run: java -jar mcreleaser-cli.jar
Multiple Files Upload
export GITHUB_TOKEN="ghp_..."
export GITHUB_REPOSITORY="user/my-plugin"
export GITHUB_REF="v1.5.0"
export FILES="build/libs/*.jar build/libs/*-sources.jar"
# All matched files will be uploaded as release assets
java -jar mcreleaser-cli.jar
Property Keys Source
Defined in GithubPropertyKey:
public interface GithubPropertyKey {
PropertyPrefix GITHUB = new PropertyPrefix("github");
PropertyKey TOKEN = GITHUB.key("token");
PropertyKey REPOSITORY = GITHUB.key("repository");
PropertyKey REF = GITHUB.key("ref");
PropertyKey DRAFT = GITHUB.key("draft");
PropertyKey PRERELEASE = GITHUB.key("prerelease");
}
Property Name Mapping:
- Property:
githubToken → Environment: GITHUB_TOKEN
- Property:
githubRepository → Environment: GITHUB_REPOSITORY
- Property:
githubRef → Environment: GITHUB_REF
- Property:
githubDraft → Environment: GITHUB_DRAFT
- Property:
githubPrerelease → Environment: GITHUB_PRERELEASE
Error Handling
Missing Required Properties
If required properties are missing, returns empty Optional:
if (PropertyKeyUtil.isAbsentAndAnnounce(logger,
GithubPropertyKey.TOKEN,
GithubPropertyKey.REPOSITORY,
GithubPropertyKey.REF)) {
return Optional.empty();
}
GitHub API Errors
API errors are logged and the process is stopped:
try {
GitHub gitHub = new GitHubBuilder()
.withOAuthToken(token)
.build();
} catch (Exception e) {
logger.error("Failed to create GitHub instance", e);
process.complete();
}
Release Already Exists
If a release with the tag already exists, it’s reused:
GHRelease release = repository.getReleaseByTagName(ref);
if (release == null) {
// Create new release
} else {
logger.info("Release already exists");
}
API Permissions
The GitHub token requires the following permissions:
repo - Full repository access
repo:status - Read commit status
repo_deployment - Read deployment status
public_repo - Access public repositories
repo:invite - Access repository invitations
For public repositories, public_repo scope is sufficient.