diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dd2f9a28..e44c604c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ on: types: [published] jobs: - publish: + publish-windows: runs-on: windows-latest steps: - name: Checkout code @@ -84,7 +84,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v4.3.3 with: - name: Artifact + name: Windows-Artifact path: | build/inno/Output/MCA_Selector_Setup.exe build/inno/Output/Signed/MCA_Selector_Setup.exe @@ -119,4 +119,74 @@ jobs: git remote set-url origin https://x-access-token:${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}@github.com/Querz/mcaselector-wiki git commit -am "Automated version update to 2.6.1" git push - shell: bash \ No newline at end of file + shell: bash + + publish-macos: + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4.1.3 + + - name: Set up JDK 21 + uses: actions/setup-java@v4.2.1 + with: + distribution: temurin + java-version: 21 + + - name: Build jar + run: ./gradlew build shadowJar --stacktrace --warning-mode all + + - name: Initialize macOS resources + run: ./installer/init-macos . + + - name: Create macOS app bundle and DMG + run: | + # Read version from gradle.properties + VERSION=$(grep '^version=' gradle.properties | cut -d'=' -f2) + JAVAFX_JMODS="build/macos/javafx-jmods" + + # Create custom runtime with jlink (properly includes JavaFX native libraries) + echo "Creating custom runtime with jlink..." + jlink \ + --module-path "$JAVA_HOME/jmods:$JAVAFX_JMODS" \ + --add-modules java.base,java.desktop,java.logging,java.management,java.naming,java.sql,java.scripting,java.xml,jdk.unsupported,javafx.controls,javafx.swing,javafx.graphics,javafx.base \ + --output build/macos/runtime \ + --strip-debug \ + --no-header-files \ + --no-man-pages \ + --compress zip-6 + + # Create the app using jpackage with custom runtime + echo "Creating DMG with jpackage..." + jpackage \ + --type dmg \ + --name "MCA Selector" \ + --app-version "$VERSION" \ + --vendor "Querz" \ + --copyright "$(grep 'application.copyright=' gradle.properties | cut -d'=' -f2)" \ + --description "A tool to select chunks from Minecraft worlds for deletion or export" \ + --icon build/macos/icon.icns \ + --input build/macos \ + --main-jar mcaselector.jar \ + --main-class net.querz.mcaselector.Main \ + --dest build/macos/output \ + --runtime-image build/macos/runtime \ + --java-options "-Xmx4G" \ + --license-file build/macos/LICENSE \ + --mac-package-identifier net.querz.mcaselector \ + --mac-package-name "MCA Selector" + + # Rename output to consistent name + mv "build/macos/output/MCA Selector-$VERSION.dmg" "build/macos/output/MCA_Selector_Setup.dmg" + + - name: Upload artifacts + uses: actions/upload-artifact@v4.3.3 + with: + name: macOS-Artifact + path: build/macos/output/MCA_Selector_Setup.dmg + + - name: Upload assets + uses: AButler/upload-release-assets@v3.0 + with: + files: build/macos/output/MCA_Selector_Setup.dmg + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/installer/init-macos b/installer/init-macos new file mode 100755 index 00000000..be31f374 --- /dev/null +++ b/installer/init-macos @@ -0,0 +1,125 @@ +#!/bin/bash + +# macOS installer initialization script +# Usage: installer/init-macos + +set -e + +gradlePropertiesFile="$1/gradle.properties" + +ReadGradleProperty() { + local value=$(cat "$gradlePropertiesFile" | grep "^$1=" | cut -d'=' -f2) + echo "$value" +} + +projectName='mcaselector' +applicationName=$(ReadGradleProperty 'application.name') +applicationVersion=$(ReadGradleProperty 'version') +applicationCopyright=$(ReadGradleProperty 'application.copyright') + +echo "Building macOS installer for $applicationName v$applicationVersion" + +# Create output directory +macosDir="$1/build/macos" +mkdir -p "$macosDir" + +# Detect architecture +ARCH=$(uname -m) +if [ "$ARCH" = "arm64" ]; then + JAVAFX_ARCH="aarch64" +else + JAVAFX_ARCH="x64" +fi + +# Download JavaFX jmods if not present (needed for jlink to create runtime with natives) +JAVAFX_VERSION="21.0.5" +JAVAFX_JMODS_DIR="$macosDir/javafx-jmods" +if [ ! -d "$JAVAFX_JMODS_DIR" ]; then + echo "Downloading JavaFX jmods $JAVAFX_VERSION for osx-$JAVAFX_ARCH..." + JAVAFX_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip" + curl -L -o "$macosDir/javafx-jmods.zip" "$JAVAFX_URL" + unzip -q "$macosDir/javafx-jmods.zip" -d "$macosDir" + mv "$macosDir/javafx-jmods-$JAVAFX_VERSION" "$JAVAFX_JMODS_DIR" + rm "$macosDir/javafx-jmods.zip" + echo "JavaFX jmods downloaded to $JAVAFX_JMODS_DIR" +fi + +# Create .icns from PNG icon +echo "Creating macOS icon..." +iconsetDir="$macosDir/icon.iconset" +mkdir -p "$iconsetDir" + +sourceIcon="$1/src/main/resources/img/icon.png" + +# Generate all required icon sizes +sips -z 16 16 "$sourceIcon" --out "$iconsetDir/icon_16x16.png" >/dev/null +sips -z 32 32 "$sourceIcon" --out "$iconsetDir/icon_16x16@2x.png" >/dev/null +sips -z 32 32 "$sourceIcon" --out "$iconsetDir/icon_32x32.png" >/dev/null +sips -z 64 64 "$sourceIcon" --out "$iconsetDir/icon_32x32@2x.png" >/dev/null +sips -z 128 128 "$sourceIcon" --out "$iconsetDir/icon_128x128.png" >/dev/null +sips -z 256 256 "$sourceIcon" --out "$iconsetDir/icon_128x128@2x.png" >/dev/null +sips -z 256 256 "$sourceIcon" --out "$iconsetDir/icon_256x256.png" >/dev/null +sips -z 512 512 "$sourceIcon" --out "$iconsetDir/icon_256x256@2x.png" >/dev/null +sips -z 512 512 "$sourceIcon" --out "$iconsetDir/icon_512x512.png" >/dev/null +sips -z 1024 1024 "$sourceIcon" --out "$iconsetDir/icon_512x512@2x.png" >/dev/null + +iconutil -c icns "$iconsetDir" -o "$macosDir/icon.icns" +rm -rf "$iconsetDir" +echo "Icon created: $macosDir/icon.icns" + +# Prepare combined license file +echo "Preparing license file..." +finalLicense=$(<"$1/LICENSE") +finalLicense="$finalLicense + + +############################################################ +############################################################ +## +## 3RD PARTY LICENSES +## +############################################################ +############################################################" + +# Add dependency licenses +if [ -d "$1/build/resources/main/licenses" ]; then + for f in "$1/build/resources/main/licenses/"*; do + if [ -f "$f" ]; then + baseName=$(basename "$f" .txt) + licenseName=$(echo "$baseName" | tr '[:lower:]' '[:upper:]') + content=$(<"$f") + finalLicense="$finalLicense + + +############################################################ +# License for $licenseName +############################################################ + +$content" + fi + done +fi + +# Add font licenses +for fontLicense in "$1/build/resources/main/font/license/"*.txt; do + if [ -f "$fontLicense" ]; then + baseName=$(basename "$fontLicense" .txt) + licenseName=$(echo "$baseName" | tr '[:lower:]' '[:upper:]') + content=$(<"$fontLicense") + finalLicense="$finalLicense + + +############################################################ +# License for $licenseName +############################################################ + +$content" + fi +done + +echo "$finalLicense" > "$macosDir/LICENSE" + +# Copy the shadow JAR +cp "$1/build/libs/$projectName-$applicationVersion.jar" "$macosDir/$projectName.jar" + +echo "macOS installer files prepared in $macosDir"