Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ci/java-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
21
55 changes: 55 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: CI

on:
push:
branches:
- 'mc/**'
pull_request:
branches:
- 'mc/**'
- master

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Read JDK version
id: jdk
run: echo "version=$(cat .github/ci/java-version 2>/dev/null || echo 21)" >> "$GITHUB_OUTPUT"

- name: Set up JDK ${{ steps.jdk.outputs.version }}
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ steps.jdk.outputs.version }}

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Build
run: |
chmod +x ./gradlew
# Mark CI jars distinctly (e.g. hotbaaaar-1.21.1-forge-ci-a1b2c3d.jar) so they're never
# mistaken for a release build; -P overrides the in-repo dev mod_version.
base="$(grep '^mod_version=' gradle.properties | cut -d= -f2)"
base="${base%-*}"
./gradlew build --no-daemon --stacktrace -Pmod_version="${base}-ci-${GITHUB_SHA:0:7}"

- name: Compute artifact name
id: meta
run: echo "name=$(echo '${{ github.ref_name }}' | tr '/:' '__')" >> "$GITHUB_OUTPUT"

- name: Upload jars
uses: actions/upload-artifact@v4
with:
name: ${{ steps.meta.outputs.name }}-jars
path: |
build/libs/*.jar
!build/libs/*-sources.jar
if-no-files-found: error
102 changes: 102 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
# Discover every target branch (mc/<version>-<loader>) so new ports are picked up automatically.
discover:
runs-on: ubuntu-latest
outputs:
branches: ${{ steps.list.outputs.branches }}
steps:
- name: List mc/* branches
id: list
env:
GH_TOKEN: ${{ github.token }}
run: |
names=$(gh api "repos/${{ github.repository }}/branches?per_page=100" \
--jq '.[].name' | { grep '^mc/' || true; })
if [ -z "$names" ]; then
json='[]'
else
json=$(printf '%s\n' "$names" | jq -R . | jq -cs .)
fi
echo "Discovered target branches: $json"
echo "branches=$json" >> "$GITHUB_OUTPUT"

build:
needs: discover
if: needs.discover.outputs.branches != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
branch: ${{ fromJson(needs.discover.outputs.branches) }}
steps:
- name: Checkout ${{ matrix.branch }}
uses: actions/checkout@v4
with:
ref: ${{ matrix.branch }}

- name: Read JDK version
id: jdk
run: echo "version=$(cat .github/ci/java-version 2>/dev/null || echo 21)" >> "$GITHUB_OUTPUT"

- name: Set up JDK ${{ steps.jdk.outputs.version }}
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ steps.jdk.outputs.version }}

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Build
run: |
chmod +x ./gradlew
# Combine this branch's "<mcver>-<loader>" prefix with the release tag version so the jar is
# named e.g. hotbaaaar-1.21.1-forge-1.0.0.jar. -P overrides gradle.properties mod_version.
base="$(grep '^mod_version=' gradle.properties | cut -d= -f2)"
base="${base%-*}"
version="${GITHUB_REF_NAME#v}"
echo "Building ${base} @ ${version}"
./gradlew build --no-daemon --stacktrace -Pmod_version="${base}-${version}"

- name: Compute artifact name
id: meta
run: echo "name=$(echo '${{ matrix.branch }}' | tr '/:' '__')" >> "$GITHUB_OUTPUT"

- name: Upload jars
uses: actions/upload-artifact@v4
with:
name: jars-${{ steps.meta.outputs.name }}
path: |
build/libs/*.jar
!build/libs/*-sources.jar
if-no-files-found: error

release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all jars
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: jars-*
merge-multiple: true

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/**/*.jar
generate_release_notes: true
fail_on_unmatched_files: true
47 changes: 47 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Building HotBaaaar (multi-version / multi-loader)

This repository uses a **branch matrix**. Each Minecraft version + mod loader combination lives on
its own self-contained, buildable branch. The `master` branch is a **hub**: it holds the CI/release
workflows and this document, but no mod project.

## Branch convention

```
mc/<mc-version>-<loader>
```

Examples: `mc/1.19.2-forge`, `mc/1.20.1-neoforge`, `mc/1.21.1-fabric`.

Each target branch is a complete project (its own `build.gradle`, sources, and `mods.toml` /
`fabric.mod.json`) and carries:

- `.github/workflows/*` — inherited from `master`, so push-CI runs on the branch.
- `.github/ci/java-version` — the JDK used to **run Gradle** on that branch (e.g. `17` for the
Forge 1.19.2 branch, which uses ForgeGradle 6 + Gradle 8.1.1). The JDK used to **compile** the mod
is provisioned automatically by Gradle's toolchain via the `foojay-resolver` plugin.

## CI (`.github/workflows/ci.yml`)

On every push to `mc/**` and on PRs into `mc/**` or `master`, the branch is built with
`./gradlew build` and the resulting jars are uploaded as a workflow artifact.

## Release (`.github/workflows/release.yml`)

Push a tag matching `v*` (e.g. `v1.0.0`) on `master`. The workflow:

1. **discover** — lists every `mc/*` branch via the GitHub API.
2. **build** — a matrix job (`fail-fast: false`) checks out and builds each branch.
3. **release** — collects all jars and publishes a single GitHub Release for the tag.

Each jar is named from its own branch's `gradle.properties` (`mod_version`).

## Adding a new target

1. Branch from the closest existing target, e.g. `git switch -c mc/1.20.1-forge mc/1.19.2-forge`.
2. Port the code (rendering, mixin targets, loader entry point, metadata) for the new version/loader.
3. Update `.github/ci/java-version` if the new build needs a different JDK to run Gradle.
4. `git push -u origin mc/1.20.1-forge` → CI builds it automatically.
5. Next `v*` tag on `master` includes it in the release automatically.

> Note: each branch carries its own copy of the workflows. If you change `ci.yml`, merge the change
> into the target branches. `release.yml` only needs to be current on the tagged `master` commit.
Loading