name: Release # Publishing a release builds every Minecraft version and attaches the mod jars # to it. mod_version in gradle.properties is the source of truth: the release # tag must match it (a leading "v" is allowed), so bump mod_version in a PR # before tagging the release. # # To (re)attach jars to an existing release, run this workflow manually with # the release's tag. on: release: types: [published] workflow_dispatch: inputs: tag: description: Tag of the existing release to build and attach jars to required: true permissions: contents: write env: TAG: ${{ github.event.release.tag_name || inputs.tag }} # The public address. Uploads go through the Cloudflare tunnel, which caps # request bodies at 100 MB, so each mod jar must stay under that. GITEA_API: ${{ github.server_url }}/api/v1 jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: ref: ${{ env.TAG }} submodules: true - name: Check tag matches mod_version run: | MOD_VERSION="$(sed -n 's/^mod_version=//p' gradle.properties | tr -d '[:space:]')" if [ "${TAG#v}" != "$MOD_VERSION" ]; then echo "::error::Release tag '$TAG' doesn't match mod_version '$MOD_VERSION' in gradle.properties. Bump mod_version to '${TAG#v}' on the release branch, or tag the release '$MOD_VERSION'." >&2 exit 1 fi echo "Building Saturn Client $MOD_VERSION" # The JDK comes from the runner's tool cache. `cache: gradle` stores Gradle's # dependencies, Loom's Minecraft cache and the build cache in the runner's # actions cache. # 1.21.x builds with Java 21 and 26.x with Java 25. The last version listed is the default # (Gradle runs on it), and the Gradle commands below point toolchain detection at both. - name: Set up Java 25 and 21 uses: actions/setup-java@v5 with: distribution: temurin java-version: | 25 21 cache: gradle - name: Build all versions run: | chmod +x gradlew # buildAll remaps every Minecraft version (two at a time, to stay within the # Gradle heap) into build/allJars. ./gradlew buildAll --no-daemon --stacktrace \ -Porg.gradle.java.installations.fromEnv=JAVA_HOME_21_X64,JAVA_HOME_25_X64 - name: Upload jars to the release env: TOKEN: ${{ secrets.GITEA_TOKEN }} REPO: ${{ github.repository }} run: | shopt -s nullglob jars=(build/allJars/*.jar) if [ ${#jars[@]} -eq 0 ]; then echo "No jars found in build/allJars" >&2 exit 1 fi # Cloudflare in front of the server rejects uploads of 100 MB or more. for jar in "${jars[@]}"; do size=$(stat -c%s "$jar") if [ "$size" -ge 100000000 ]; then echo "::error::$(basename "$jar") is $((size / 1000000)) MB; uploads must be under 100 MB. Check what's taking space with: unzip -l \"$jar\" | sort -n" >&2 exit 1 fi done # Look the release up by tag so manual runs work too. RELEASE_ID="$(curl --fail-with-body -sS -H "Authorization: token $TOKEN" \ "$GITEA_API/repos/$REPO/releases/tags/$TAG" \ | grep -o '"id":[0-9]*' | head -n1 | cut -d: -f2)" if [ -z "$RELEASE_ID" ]; then echo "No release found for tag $TAG" >&2 exit 1 fi for jar in "${jars[@]}"; do echo "Uploading $(basename "$jar") to release $TAG ($RELEASE_ID)" curl --fail-with-body -sS -X POST \ -H "Authorization: token $TOKEN" \ -F "attachment=@$jar" \ "$GITEA_API/repos/$REPO/releases/$RELEASE_ID/assets" echo done