diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index c45c66c..6f91449 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -21,39 +21,78 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Java 21 + uses: actions/setup-java@v4 with: java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - cache: 'maven' + distribution: 'temurin' + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable - - name: Build JAR with Maven - run: mvn -B clean package --file pom.xml + - name: Install jbundle from source + run: | + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c + cargo install --path . + + - name: Build with jbundle + run: | + mkdir -p dist + jbundle build --input . --output dist/SpriteLab --java-version 21 --target linux-x64 --profile cli - - name: Verify JAR was created + - name: Verify jbundle binary was created run: | - if [ ! -f target/SpriteLab.jar ]; then - echo "Error: SpriteLab.jar was not created" + if [ ! -f dist/SpriteLab ]; then + echo "Error: jbundle binary SpriteLab was not created" exit 1 fi - echo "JAR build successful: SpriteLab.jar created" - ls -lh target/SpriteLab.jar + echo "jbundle binary created successfully" + ls -lh dist/SpriteLab + file dist/SpriteLab - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml - - - name: Verify native binary was created + - name: Test binary launches (headless) run: | - if [ ! -f target/SpriteLab ]; then - echo "Error: Native binary SpriteLab was not created" + # Install Xvfb for headless testing of JavaFX GUI + sudo apt-get update + sudo apt-get install -y xvfb libgtk-3-0 + + # Make binary executable + chmod +x dist/SpriteLab + + # Try to launch the app in headless mode + # JavaFX apps will start and we can verify no immediate crashes + echo "Testing binary launch..." + + # Run in background and capture output + xvfb-run -a dist/SpriteLab > /tmp/spritelab.log 2>&1 & + LAUNCH_PID=$! + + # Wait for app to start (give it time to initialize) + echo "Waiting for application to start..." + sleep 8 + + # Check if process is still running (means it started successfully) + if ps -p $LAUNCH_PID > /dev/null 2>&1; then + echo "✓ Binary launched successfully and is running (PID: $LAUNCH_PID)" + # Clean up + kill $LAUNCH_PID 2>/dev/null || true + sleep 1 + kill -9 $LAUNCH_PID 2>/dev/null || true + exit 0 + else + # Process already exited - check why + wait $LAUNCH_PID + EXIT_CODE=$? + echo "✗ Binary exited with code: $EXIT_CODE" + echo "--- Application log ---" + cat /tmp/spritelab.log || true exit 1 fi - echo "Native binary created successfully" - ls -lh target/SpriteLab - file target/SpriteLab - name: Download FFmpeg for Linux run: | @@ -74,7 +113,7 @@ jobs: - name: Copy artifacts run: | - cp target/SpriteLab staging/SpriteLab + cp dist/SpriteLab staging/SpriteLab cp run-native.sh staging/ || true cp README.md staging/ || cp Readme.md staging/ || true cp LICENSE staging/ || true @@ -105,39 +144,74 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Java 21 + uses: actions/setup-java@v4 with: java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - cache: 'maven' + distribution: 'temurin' + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Install jbundle from source + run: | + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c + cargo install --path . - - name: Build JAR with Maven - run: mvn -B clean package --file pom.xml + - name: Build with jbundle + run: | + mkdir -p dist + jbundle build --input . --output dist/SpriteLab --java-version 21 --target macos-aarch64 --profile cli - - name: Verify JAR was created + - name: Verify jbundle binary was created run: | - if [ ! -f target/SpriteLab.jar ]; then - echo "Error: SpriteLab.jar was not created" + if [ ! -f dist/SpriteLab ]; then + echo "Error: jbundle binary SpriteLab was not created" exit 1 fi - echo "JAR build successful: SpriteLab.jar created" - ls -lh target/SpriteLab.jar + echo "jbundle binary created successfully" + ls -lh dist/SpriteLab + file dist/SpriteLab - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml - - - name: Verify native binary was created + - name: Test binary launches run: | - if [ ! -f target/SpriteLab ]; then - echo "Error: Native binary SpriteLab was not created" + # Make binary executable + chmod +x dist/SpriteLab + + # Try to launch the app + # On macOS, JavaFX apps can run but may need display access + echo "Testing binary launch..." + + # Run in background and capture output + dist/SpriteLab > /tmp/spritelab.log 2>&1 & + LAUNCH_PID=$! + + # Wait for app to start (give it time to initialize) + echo "Waiting for application to start..." + sleep 8 + + # Check if process is still running (means it started successfully) + if ps -p $LAUNCH_PID > /dev/null 2>&1; then + echo "✓ Binary launched successfully and is running (PID: $LAUNCH_PID)" + # Clean up + kill $LAUNCH_PID 2>/dev/null || true + sleep 1 + kill -9 $LAUNCH_PID 2>/dev/null || true + exit 0 + else + # Process already exited - check why + wait $LAUNCH_PID + EXIT_CODE=$? + echo "✗ Binary exited with code: $EXIT_CODE" + echo "--- Application log ---" + cat /tmp/spritelab.log || true exit 1 fi - echo "Native binary created successfully" - ls -lh target/SpriteLab - file target/SpriteLab - name: Download FFmpeg for macOS ARM64 run: | @@ -160,7 +234,7 @@ jobs: - name: Copy artifacts run: | - cp target/SpriteLab staging/SpriteLab + cp dist/SpriteLab staging/SpriteLab cp run-native.sh staging/ || true cp README.md staging/ || cp Readme.md staging/ || true cp LICENSE staging/ || true diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml index 0eb37c8..0790d8c 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -18,28 +18,39 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Java 21 + uses: actions/setup-java@v4 with: java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: 'true' - cache: 'maven' + distribution: 'temurin' + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml + - name: Install jbundle from source + run: | + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c + cargo install --path . + + - name: Build with jbundle + run: | + mkdir -p dist + jbundle build --input . --output dist/SpriteLab --java-version 21 --target linux-x64 --profile cli - - name: Verify native binary was created + - name: Verify jbundle binary was created run: | - if [ ! -f target/SpriteLab ]; then - echo "Error: Native binary SpriteLab was not created" + if [ ! -f dist/SpriteLab ]; then + echo "Error: jbundle binary SpriteLab was not created" exit 1 fi - echo "Native binary created successfully" - ls -lh target/SpriteLab - file target/SpriteLab + echo "jbundle binary created successfully" + ls -lh dist/SpriteLab + file dist/SpriteLab - name: Download FFmpeg for Linux run: | @@ -52,7 +63,7 @@ jobs: - name: Copy artifacts run: | - cp target/SpriteLab staging/SpriteLab + cp dist/SpriteLab staging/SpriteLab cp run-native.sh staging/ || true cp README.md staging/ || cp Readme.md staging/ || true cp LICENSE staging/ || true @@ -81,28 +92,39 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Java 21 + uses: actions/setup-java@v4 with: java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: 'true' - cache: 'maven' + distribution: 'temurin' + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml + - name: Install jbundle from source + run: | + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c + cargo install --path . + + - name: Build with jbundle + run: | + mkdir -p dist + jbundle build --input . --output dist/SpriteLab --java-version 21 --target macos-aarch64 --profile cli - - name: Verify native binary was created + - name: Verify jbundle binary was created run: | - if [ ! -f target/SpriteLab ]; then - echo "Error: Native binary SpriteLab was not created" + if [ ! -f dist/SpriteLab ]; then + echo "Error: jbundle binary SpriteLab was not created" exit 1 fi - echo "Native binary created successfully" - ls -lh target/SpriteLab - file target/SpriteLab + echo "jbundle binary created successfully" + ls -lh dist/SpriteLab + file dist/SpriteLab - name: Download FFmpeg for macOS ARM64 run: | @@ -117,7 +139,7 @@ jobs: - name: Copy artifacts run: | - cp target/SpriteLab staging/SpriteLab + cp dist/SpriteLab staging/SpriteLab cp run-native.sh staging/ || true cp README.md staging/ || cp Readme.md staging/ || true cp LICENSE staging/ || true diff --git a/Readme.md b/Readme.md index 3d99e5b..5cddcca 100644 --- a/Readme.md +++ b/Readme.md @@ -63,7 +63,7 @@ This tool is built for **creators**. It serves as the ideal bridge for: ### Binary Releases (Recommended - No Java Required) -Native binary releases are available for Linux and macOS from the [GitHub Releases](https://github.com/katamini/SpriteLab/releases) page. These are standalone executables that **do not require Java** to be installed. +Self-contained binary releases are available for Linux and macOS from the [GitHub Releases](https://github.com/katamini/SpriteLab/releases) page. These binaries are built with jbundle and include an embedded JVM - **no Java installation required!** **Linux (amd64):** 1. Download `SpriteLab-Linux-amd64.tar.gz` from the latest release @@ -75,13 +75,17 @@ Native binary releases are available for Linux and macOS from the [GitHub Releas 2. Extract: `tar -xzf SpriteLab-macOS-arm64.tar.gz` 3. Run: `./run-native.sh` or `./SpriteLab` -Both packages include FFmpeg binaries in the `bin` folder. +Both packages include: +- Self-contained SpriteLab binary with embedded JVM (built with jbundle) +- FFmpeg binaries in the `bin` folder -### Alternative Installation (RAR Release - Windows) +### Alternative Installation (Windows) +For Windows, jbundle support is not yet available. You can use the traditional JAR-based release: 1. Download the `.rar` file from [Itch.io](https://fedeiatech.itch.io/spritelab). 2. Extract the contents (Ensure the `bin` folder containing `ffmpeg.exe` is in the same directory). -3. Run `SpriteLab.exe`. +3. Requires Java 21 or higher to be installed +4. Run `SpriteLab.exe` or `java -jar SpriteLab.jar` --- @@ -89,23 +93,47 @@ Both packages include FFmpeg binaries in the `bin` folder. * **Language:** Java 21 (JavaFX). * **Dependencies:** FFmpeg (Local binaries required in `/bin`). +* **Build Tool:** jbundle (creates self-contained binaries with no JVM required). * **License:** MIT. -**Building from source:** +**Building from source with jbundle:** + +jbundle packages your Java application into a self-contained binary with an embedded JVM - no Java installation required to run! ```bash -# Build JAR (requires Java 21) -mvn clean package +# Install jbundle (requires Rust/Cargo) +git clone https://github.com/avelino/jbundle.git +cd jbundle +# Pin to a specific version for reproducible builds +git checkout f722ab543a57e7fc496656c72198c71efe52e89c +cargo install --path . + +# Build self-contained binary (no JVM needed to run!) +cd /path/to/SpriteLab + +# For Linux (amd64) +jbundle build --input . --output ./dist/SpriteLab --java-version 21 --target linux-x64 --profile cli -# Build native binary (requires GraalVM 21 with native-image) -mvn -Pnative clean package +# For macOS ARM64 (Apple Silicon) +jbundle build --input . --output ./dist/SpriteLab --java-version 21 --target macos-aarch64 --profile cli + +# Note: Windows is not yet supported by jbundle + +# The output binary includes everything needed to run - no Java required! +``` + +**Alternative: Traditional Maven Build (requires Java 21 to run):** + +```bash +# Build JAR (requires Java 21 to run) +mvn clean package ``` ### GitHub Actions & Release Process -The repository includes automated build workflows: +The repository includes automated build workflows using jbundle: -* **CI Build** (`.github/workflows/ci-build.yml`): Runs on every push/PR to test both JAR and native builds for Linux and macOS +* **CI Build** (`.github/workflows/ci-build.yml`): Runs on every push/PR to build and test self-contained binaries for Linux and macOS * **Release Builds** (`.github/workflows/release-builds.yml`): Automatically creates distribution packages on GitHub releases **To create a new release:** @@ -113,16 +141,21 @@ The repository includes automated build workflows: 2. Push the tag: `git push origin v0.3.2` 3. Create a GitHub release from the tag 4. The workflow will automatically build and attach: - - `SpriteLab-Linux-amd64.tar.gz` (Linux native binary + FFmpeg) - - `SpriteLab-macOS-arm64.tar.gz` (macOS ARM64 native binary + FFmpeg) - -**GraalVM Native Image Configuration:** - -JavaFX applications require special configuration for GraalVM native-image. The configuration files are located in: -- `src/main/resources/META-INF/native-image/com.fedeiatech.spritelab/SpriteLab/` - - `reflect-config.json` - Reflection configuration for JavaFX internal classes - - `jni-config.json` - JNI configuration for native JavaFX components - - `resource-config.json` - Resource includes for FXML, CSS, and images - - `native-image.properties` - Build arguments and class initialization settings + - `SpriteLab-Linux-amd64.tar.gz` (Self-contained Linux binary + FFmpeg - no JVM required!) + - `SpriteLab-macOS-arm64.tar.gz` (Self-contained macOS ARM64 binary + FFmpeg - no JVM required!) + +Each release package includes: +- Self-contained SpriteLab binary (with embedded JVM) +- FFmpeg binary +- Launch script (`run-native.sh`) +- README and LICENSE files + +**About jbundle:** + +jbundle (https://github.com/avelino/jbundle) is a tool that packages Java applications into self-contained binaries with an embedded JDK. The resulting binaries: +- Run anywhere without requiring Java installation +- Include optimized startup with AppCDS by default +- Support CLI profile for fast startup +- Work across platforms (Linux and macOS currently supported) Developed by **FedeiaTech**. \ No newline at end of file