From b899d5e9e67341b3d76332c577f85f885de648be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:24:51 +0000 Subject: [PATCH 1/7] Initial plan From 5f7198a487cc235e77b140e6eeda12094bf57b73 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:29:10 +0000 Subject: [PATCH 2/7] Replace GraalVM native-image with jbundle for self-contained binaries Co-authored-by: lmangani <1423657+lmangani@users.noreply.github.com> --- .github/workflows/ci-build.yml | 90 ++++++++++++---------------- .github/workflows/release-builds.yml | 80 ++++++++++++++----------- Readme.md | 65 +++++++++++++------- 3 files changed, 127 insertions(+), 108 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index c45c66c..0dd9ac3 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -21,39 +21,32 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 with: - java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - cache: 'maven' + toolchain: stable - - name: Build JAR with Maven - run: mvn -B clean package --file pom.xml - - - name: Verify JAR was created + - name: Install jbundle from source run: | - if [ ! -f target/SpriteLab.jar ]; then - echo "Error: SpriteLab.jar was not created" - exit 1 - fi - echo "JAR build successful: SpriteLab.jar created" - ls -lh target/SpriteLab.jar + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + cargo install --path . - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml + - 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: | @@ -74,7 +67,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 +98,32 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 with: - java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - cache: 'maven' + toolchain: stable - - name: Build JAR with Maven - run: mvn -B clean package --file pom.xml - - - name: Verify JAR was created + - name: Install jbundle from source run: | - if [ ! -f target/SpriteLab.jar ]; then - echo "Error: SpriteLab.jar was not created" - exit 1 - fi - echo "JAR build successful: SpriteLab.jar created" - ls -lh target/SpriteLab.jar + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + cargo install --path . - - name: Build Native Binary with Maven - run: mvn -B -Pnative 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 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: | @@ -160,7 +146,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..ebceccc 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -18,28 +18,32 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 with: - java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: 'true' - cache: 'maven' - - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml + toolchain: stable + + - name: Install jbundle from source + run: | + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + 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 +56,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 +85,32 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 with: - java-version: '21' - distribution: 'graalvm' - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: 'true' - cache: 'maven' - - - name: Build Native Binary with Maven - run: mvn -B -Pnative clean package --file pom.xml + toolchain: stable + + - name: Install jbundle from source + run: | + git clone https://github.com/avelino/jbundle.git /tmp/jbundle + cd /tmp/jbundle + 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 +125,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..78f9a11 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,7 +75,9 @@ 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) @@ -89,23 +91,41 @@ 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 +cargo install --path . + +# Build self-contained binary (no JVM needed to run!) +cd /path/to/SpriteLab +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 +jbundle build --input . --output ./dist/SpriteLab --java-version 21 --target macos-aarch64 --profile cli + +# 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 self-contained binaries for Linux and macOS using jbundle * **Release Builds** (`.github/workflows/release-builds.yml`): Automatically creates distribution packages on GitHub releases **To create a new release:** @@ -113,16 +133,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, macOS, Windows) Developed by **FedeiaTech**. \ No newline at end of file From bb501972ab5ae0fbcdb80b7d8b6f857e9ce254f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:30:50 +0000 Subject: [PATCH 3/7] Add Windows support and complete multiplatform jbundle integration Co-authored-by: lmangani <1423657+lmangani@users.noreply.github.com> --- .github/workflows/ci-build.yml | 81 ++++++++++++++++++++++++++++ .github/workflows/release-builds.yml | 70 ++++++++++++++++++++++++ Readme.md | 27 ++++++---- 3 files changed, 167 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 0dd9ac3..4bc579a 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -167,3 +167,84 @@ jobs: - name: Clean staging run: rm -fr staging + + build-windows: + name: Build and Test - Windows (x64) + runs-on: windows-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - 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 C:\tmp\jbundle + cd C:\tmp\jbundle + cargo install --path . + shell: pwsh + + - name: Build with jbundle + run: | + New-Item -ItemType Directory -Force -Path dist + jbundle build --input . --output dist/SpriteLab.exe --java-version 21 --target windows-x64 --profile cli + shell: pwsh + + - name: Verify jbundle binary was created + run: | + if (-not (Test-Path dist/SpriteLab.exe)) { + Write-Error "Error: jbundle binary SpriteLab.exe was not created" + exit 1 + } + Write-Host "jbundle binary created successfully" + Get-Item dist/SpriteLab.exe + shell: pwsh + + - name: Download FFmpeg for Windows + run: | + New-Item -ItemType Directory -Force -Path staging/bin + Invoke-WebRequest -Uri "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip" -OutFile ffmpeg.zip + Expand-Archive ffmpeg.zip -DestinationPath . + Move-Item ffmpeg-*-essentials_build/bin/ffmpeg.exe staging/bin/ffmpeg.exe + Remove-Item ffmpeg.zip + Remove-Item -Recurse ffmpeg-*-essentials_build + shell: pwsh + + - name: Verify FFmpeg + run: | + if (-not (Test-Path staging/bin/ffmpeg.exe)) { + Write-Error "Error: FFmpeg binary not found" + exit 1 + } + & staging/bin/ffmpeg.exe -version | Select-Object -First 1 + shell: pwsh + + - name: Copy artifacts + run: | + Copy-Item dist/SpriteLab.exe staging/SpriteLab.exe + if (Test-Path README.md) { Copy-Item README.md staging/ } + if (Test-Path Readme.md) { Copy-Item Readme.md staging/README.md } + if (Test-Path LICENSE) { Copy-Item LICENSE staging/ } + shell: pwsh + + - name: Create test package + run: | + Compress-Archive -Path staging/* -DestinationPath SpriteLab-Windows-x64.zip + shell: pwsh + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: SpriteLab-Windows-x64 + path: SpriteLab-Windows-x64.zip + retention-days: 7 + + - name: Clean staging + run: Remove-Item -Recurse -Force staging + shell: pwsh diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml index ebceccc..5efcb1e 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -144,3 +144,73 @@ jobs: - name: Clean staging run: rm -fr staging + + build-windows: + name: Build Windows (x64) + runs-on: windows-latest + permissions: + contents: write # Required to upload release assets + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - 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 C:\tmp\jbundle + cd C:\tmp\jbundle + cargo install --path . + shell: pwsh + + - name: Build with jbundle + run: | + New-Item -ItemType Directory -Force -Path dist + jbundle build --input . --output dist/SpriteLab.exe --java-version 21 --target windows-x64 --profile cli + shell: pwsh + + - name: Verify jbundle binary was created + run: | + if (-not (Test-Path dist/SpriteLab.exe)) { + Write-Error "Error: jbundle binary SpriteLab.exe was not created" + exit 1 + } + Write-Host "jbundle binary created successfully" + Get-Item dist/SpriteLab.exe + shell: pwsh + + - name: Download FFmpeg for Windows + run: | + New-Item -ItemType Directory -Force -Path staging/bin + Invoke-WebRequest -Uri "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip" -OutFile ffmpeg.zip + Expand-Archive ffmpeg.zip -DestinationPath . + Move-Item ffmpeg-*-essentials_build/bin/ffmpeg.exe staging/bin/ffmpeg.exe + Remove-Item ffmpeg.zip + Remove-Item -Recurse ffmpeg-*-essentials_build + shell: pwsh + + - name: Copy artifacts + run: | + Copy-Item dist/SpriteLab.exe staging/SpriteLab.exe + if (Test-Path README.md) { Copy-Item README.md staging/ } + if (Test-Path Readme.md) { Copy-Item Readme.md staging/README.md } + if (Test-Path LICENSE) { Copy-Item LICENSE staging/ } + shell: pwsh + + - name: Create release package + run: | + Compress-Archive -Path staging/* -DestinationPath SpriteLab-Windows-x64.zip + shell: pwsh + + - name: Upload release asset + uses: softprops/action-gh-release@v2 + with: + files: SpriteLab-Windows-x64.zip + + - name: Clean staging + run: Remove-Item -Recurse -Force staging + shell: pwsh diff --git a/Readme.md b/Readme.md index 78f9a11..fe920a0 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) -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!** +Self-contained binary releases are available for Linux, macOS, and Windows 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,16 +75,15 @@ Self-contained binary releases are available for Linux and macOS from the [GitHu 2. Extract: `tar -xzf SpriteLab-macOS-arm64.tar.gz` 3. Run: `./run-native.sh` or `./SpriteLab` -Both packages include: +**Windows (x64):** +1. Download `SpriteLab-Windows-x64.zip` from the latest release +2. Extract the ZIP file +3. Run: `SpriteLab.exe` + +All packages include: - Self-contained SpriteLab binary with embedded JVM (built with jbundle) - FFmpeg binaries in the `bin` folder -### Alternative Installation (RAR Release - Windows) - -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`. - --- ## Development (Build) @@ -106,11 +105,16 @@ 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 -# For macOS ARM64 +# For macOS ARM64 (Apple Silicon) jbundle build --input . --output ./dist/SpriteLab --java-version 21 --target macos-aarch64 --profile cli +# For Windows (x64) +jbundle build --input . --output ./dist/SpriteLab.exe --java-version 21 --target windows-x64 --profile cli + # The output binary includes everything needed to run - no Java required! ``` @@ -125,7 +129,7 @@ mvn clean package The repository includes automated build workflows using jbundle: -* **CI Build** (`.github/workflows/ci-build.yml`): Runs on every push/PR to build self-contained binaries for Linux and macOS using jbundle +* **CI Build** (`.github/workflows/ci-build.yml`): Runs on every push/PR to build self-contained binaries for Linux, macOS, and Windows using jbundle * **Release Builds** (`.github/workflows/release-builds.yml`): Automatically creates distribution packages on GitHub releases **To create a new release:** @@ -135,11 +139,12 @@ The repository includes automated build workflows using jbundle: 4. The workflow will automatically build and attach: - `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!) + - `SpriteLab-Windows-x64.zip` (Self-contained Windows binary + FFmpeg - no JVM required!) Each release package includes: - Self-contained SpriteLab binary (with embedded JVM) - FFmpeg binary -- Launch script (`run-native.sh`) +- Launch script (`run-native.sh` for Linux/macOS) - README and LICENSE files **About jbundle:** From adf86e7fecad7bb72f8ce3f6c19d7bcac9ec23e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:33:30 +0000 Subject: [PATCH 4/7] Add runtime tests to verify binaries launch correctly Co-authored-by: lmangani <1423657+lmangani@users.noreply.github.com> --- .github/workflows/ci-build.yml | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 4bc579a..e014f54 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -47,6 +47,41 @@ jobs: echo "jbundle binary created successfully" ls -lh dist/SpriteLab file dist/SpriteLab + + - name: Test binary launches (headless) + run: | + # 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 with timeout + # JavaFX apps will start and we can verify no immediate crashes + echo "Testing binary launch..." + timeout 10s xvfb-run -a dist/SpriteLab & + LAUNCH_PID=$! + sleep 5 + + # 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" + kill $LAUNCH_PID || true + exit 0 + else + # Check if it exited with error + wait $LAUNCH_PID + EXIT_CODE=$? + if [ $EXIT_CODE -eq 124 ]; then + # Timeout means it was still running - success! + echo "✓ Binary launched successfully (timed out as expected)" + exit 0 + else + echo "✗ Binary failed to launch or crashed immediately (exit code: $EXIT_CODE)" + exit 1 + fi + fi - name: Download FFmpeg for Linux run: | @@ -124,6 +159,37 @@ jobs: echo "jbundle binary created successfully" ls -lh dist/SpriteLab file dist/SpriteLab + + - name: Test binary launches + run: | + # Make binary executable + chmod +x dist/SpriteLab + + # Try to launch the app with timeout + # On macOS, JavaFX apps can run in headless-ish mode + echo "Testing binary launch..." + timeout 10s dist/SpriteLab & + LAUNCH_PID=$! + sleep 5 + + # 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" + kill $LAUNCH_PID || true + exit 0 + else + # Check if it exited with error + wait $LAUNCH_PID + EXIT_CODE=$? + if [ $EXIT_CODE -eq 124 ]; then + # Timeout means it was still running - success! + echo "✓ Binary launched successfully (timed out as expected)" + exit 0 + else + echo "✗ Binary failed to launch or crashed immediately (exit code: $EXIT_CODE)" + exit 1 + fi + fi - name: Download FFmpeg for macOS ARM64 run: | From ea88bc334ab392d0db0d934675bf5135966aa9c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:36:02 +0000 Subject: [PATCH 5/7] Pin jbundle version and remove Windows support (not yet supported) Co-authored-by: lmangani <1423657+lmangani@users.noreply.github.com> --- .github/workflows/ci-build.yml | 83 +--------------------------- .github/workflows/release-builds.yml | 72 +----------------------- Readme.md | 27 +++++---- 3 files changed, 19 insertions(+), 163 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index e014f54..b839eb3 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -31,6 +31,7 @@ jobs: run: | git clone https://github.com/avelino/jbundle.git /tmp/jbundle cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c cargo install --path . - name: Build with jbundle @@ -143,6 +144,7 @@ jobs: run: | git clone https://github.com/avelino/jbundle.git /tmp/jbundle cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c cargo install --path . - name: Build with jbundle @@ -233,84 +235,3 @@ jobs: - name: Clean staging run: rm -fr staging - - build-windows: - name: Build and Test - Windows (x64) - runs-on: windows-latest - permissions: - contents: read - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - 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 C:\tmp\jbundle - cd C:\tmp\jbundle - cargo install --path . - shell: pwsh - - - name: Build with jbundle - run: | - New-Item -ItemType Directory -Force -Path dist - jbundle build --input . --output dist/SpriteLab.exe --java-version 21 --target windows-x64 --profile cli - shell: pwsh - - - name: Verify jbundle binary was created - run: | - if (-not (Test-Path dist/SpriteLab.exe)) { - Write-Error "Error: jbundle binary SpriteLab.exe was not created" - exit 1 - } - Write-Host "jbundle binary created successfully" - Get-Item dist/SpriteLab.exe - shell: pwsh - - - name: Download FFmpeg for Windows - run: | - New-Item -ItemType Directory -Force -Path staging/bin - Invoke-WebRequest -Uri "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip" -OutFile ffmpeg.zip - Expand-Archive ffmpeg.zip -DestinationPath . - Move-Item ffmpeg-*-essentials_build/bin/ffmpeg.exe staging/bin/ffmpeg.exe - Remove-Item ffmpeg.zip - Remove-Item -Recurse ffmpeg-*-essentials_build - shell: pwsh - - - name: Verify FFmpeg - run: | - if (-not (Test-Path staging/bin/ffmpeg.exe)) { - Write-Error "Error: FFmpeg binary not found" - exit 1 - } - & staging/bin/ffmpeg.exe -version | Select-Object -First 1 - shell: pwsh - - - name: Copy artifacts - run: | - Copy-Item dist/SpriteLab.exe staging/SpriteLab.exe - if (Test-Path README.md) { Copy-Item README.md staging/ } - if (Test-Path Readme.md) { Copy-Item Readme.md staging/README.md } - if (Test-Path LICENSE) { Copy-Item LICENSE staging/ } - shell: pwsh - - - name: Create test package - run: | - Compress-Archive -Path staging/* -DestinationPath SpriteLab-Windows-x64.zip - shell: pwsh - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: SpriteLab-Windows-x64 - path: SpriteLab-Windows-x64.zip - retention-days: 7 - - - name: Clean staging - run: Remove-Item -Recurse -Force staging - shell: pwsh diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml index 5efcb1e..052c2f6 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -28,6 +28,7 @@ jobs: run: | git clone https://github.com/avelino/jbundle.git /tmp/jbundle cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c cargo install --path . - name: Build with jbundle @@ -95,6 +96,7 @@ jobs: run: | git clone https://github.com/avelino/jbundle.git /tmp/jbundle cd /tmp/jbundle + git checkout f722ab543a57e7fc496656c72198c71efe52e89c cargo install --path . - name: Build with jbundle @@ -144,73 +146,3 @@ jobs: - name: Clean staging run: rm -fr staging - - build-windows: - name: Build Windows (x64) - runs-on: windows-latest - permissions: - contents: write # Required to upload release assets - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - 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 C:\tmp\jbundle - cd C:\tmp\jbundle - cargo install --path . - shell: pwsh - - - name: Build with jbundle - run: | - New-Item -ItemType Directory -Force -Path dist - jbundle build --input . --output dist/SpriteLab.exe --java-version 21 --target windows-x64 --profile cli - shell: pwsh - - - name: Verify jbundle binary was created - run: | - if (-not (Test-Path dist/SpriteLab.exe)) { - Write-Error "Error: jbundle binary SpriteLab.exe was not created" - exit 1 - } - Write-Host "jbundle binary created successfully" - Get-Item dist/SpriteLab.exe - shell: pwsh - - - name: Download FFmpeg for Windows - run: | - New-Item -ItemType Directory -Force -Path staging/bin - Invoke-WebRequest -Uri "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip" -OutFile ffmpeg.zip - Expand-Archive ffmpeg.zip -DestinationPath . - Move-Item ffmpeg-*-essentials_build/bin/ffmpeg.exe staging/bin/ffmpeg.exe - Remove-Item ffmpeg.zip - Remove-Item -Recurse ffmpeg-*-essentials_build - shell: pwsh - - - name: Copy artifacts - run: | - Copy-Item dist/SpriteLab.exe staging/SpriteLab.exe - if (Test-Path README.md) { Copy-Item README.md staging/ } - if (Test-Path Readme.md) { Copy-Item Readme.md staging/README.md } - if (Test-Path LICENSE) { Copy-Item LICENSE staging/ } - shell: pwsh - - - name: Create release package - run: | - Compress-Archive -Path staging/* -DestinationPath SpriteLab-Windows-x64.zip - shell: pwsh - - - name: Upload release asset - uses: softprops/action-gh-release@v2 - with: - files: SpriteLab-Windows-x64.zip - - - name: Clean staging - run: Remove-Item -Recurse -Force staging - shell: pwsh diff --git a/Readme.md b/Readme.md index fe920a0..95e0ac6 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) -Self-contained binary releases are available for Linux, macOS, and Windows 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!** +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,15 +75,18 @@ Self-contained binary releases are available for Linux, macOS, and Windows from 2. Extract: `tar -xzf SpriteLab-macOS-arm64.tar.gz` 3. Run: `./run-native.sh` or `./SpriteLab` -**Windows (x64):** -1. Download `SpriteLab-Windows-x64.zip` from the latest release -2. Extract the ZIP file -3. Run: `SpriteLab.exe` - -All packages include: +Both packages include: - Self-contained SpriteLab binary with embedded JVM (built with jbundle) - FFmpeg binaries in the `bin` folder +### 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. Requires Java 21 or higher to be installed +4. Run `SpriteLab.exe` or `java -jar SpriteLab.jar` + --- ## Development (Build) @@ -101,6 +104,8 @@ jbundle packages your Java application into a self-contained binary with an embe # 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!) @@ -112,8 +117,7 @@ jbundle build --input . --output ./dist/SpriteLab --java-version 21 --target lin # For macOS ARM64 (Apple Silicon) jbundle build --input . --output ./dist/SpriteLab --java-version 21 --target macos-aarch64 --profile cli -# For Windows (x64) -jbundle build --input . --output ./dist/SpriteLab.exe --java-version 21 --target windows-x64 --profile cli +# Note: Windows is not yet supported by jbundle # The output binary includes everything needed to run - no Java required! ``` @@ -129,7 +133,7 @@ mvn clean package The repository includes automated build workflows using jbundle: -* **CI Build** (`.github/workflows/ci-build.yml`): Runs on every push/PR to build self-contained binaries for Linux, macOS, and Windows using jbundle +* **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:** @@ -139,12 +143,11 @@ The repository includes automated build workflows using jbundle: 4. The workflow will automatically build and attach: - `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!) - - `SpriteLab-Windows-x64.zip` (Self-contained Windows binary + FFmpeg - no JVM required!) Each release package includes: - Self-contained SpriteLab binary (with embedded JVM) - FFmpeg binary -- Launch script (`run-native.sh` for Linux/macOS) +- Launch script (`run-native.sh`) - README and LICENSE files **About jbundle:** From 7bea41e687a9b62ab4021f8aa7b55a9825539a83 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:37:44 +0000 Subject: [PATCH 6/7] Fix documentation inconsistency and improve runtime test reliability Co-authored-by: lmangani <1423657+lmangani@users.noreply.github.com> --- .github/workflows/ci-build.yml | 66 +++++++++++++++++++--------------- Readme.md | 2 +- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index b839eb3..a54e30a 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -58,30 +58,34 @@ jobs: # Make binary executable chmod +x dist/SpriteLab - # Try to launch the app in headless mode with timeout + # Try to launch the app in headless mode # JavaFX apps will start and we can verify no immediate crashes echo "Testing binary launch..." - timeout 10s xvfb-run -a dist/SpriteLab & + + # Run in background and capture output + xvfb-run -a dist/SpriteLab > /tmp/spritelab.log 2>&1 & LAUNCH_PID=$! - sleep 5 + + # 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" - kill $LAUNCH_PID || true + 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 - # Check if it exited with error + # Process already exited - check why wait $LAUNCH_PID EXIT_CODE=$? - if [ $EXIT_CODE -eq 124 ]; then - # Timeout means it was still running - success! - echo "✓ Binary launched successfully (timed out as expected)" - exit 0 - else - echo "✗ Binary failed to launch or crashed immediately (exit code: $EXIT_CODE)" - exit 1 - fi + echo "✗ Binary exited with code: $EXIT_CODE" + echo "--- Application log ---" + cat /tmp/spritelab.log || true + exit 1 fi - name: Download FFmpeg for Linux @@ -167,30 +171,34 @@ jobs: # Make binary executable chmod +x dist/SpriteLab - # Try to launch the app with timeout - # On macOS, JavaFX apps can run in headless-ish mode + # Try to launch the app + # On macOS, JavaFX apps can run but may need display access echo "Testing binary launch..." - timeout 10s dist/SpriteLab & + + # Run in background and capture output + dist/SpriteLab > /tmp/spritelab.log 2>&1 & LAUNCH_PID=$! - sleep 5 + + # 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" - kill $LAUNCH_PID || true + 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 - # Check if it exited with error + # Process already exited - check why wait $LAUNCH_PID EXIT_CODE=$? - if [ $EXIT_CODE -eq 124 ]; then - # Timeout means it was still running - success! - echo "✓ Binary launched successfully (timed out as expected)" - exit 0 - else - echo "✗ Binary failed to launch or crashed immediately (exit code: $EXIT_CODE)" - exit 1 - fi + echo "✗ Binary exited with code: $EXIT_CODE" + echo "--- Application log ---" + cat /tmp/spritelab.log || true + exit 1 fi - name: Download FFmpeg for macOS ARM64 diff --git a/Readme.md b/Readme.md index 95e0ac6..5cddcca 100644 --- a/Readme.md +++ b/Readme.md @@ -156,6 +156,6 @@ jbundle (https://github.com/avelino/jbundle) is a tool that packages Java applic - Run anywhere without requiring Java installation - Include optimized startup with AppCDS by default - Support CLI profile for fast startup -- Work across platforms (Linux, macOS, Windows) +- Work across platforms (Linux and macOS currently supported) Developed by **FedeiaTech**. \ No newline at end of file From 113573e6f65d6dec91c7875892e402e1ac5c12c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:56:04 +0000 Subject: [PATCH 7/7] Add Java 21 setup for jbundle to compile Java source Co-authored-by: lmangani <1423657+lmangani@users.noreply.github.com> --- .github/workflows/ci-build.yml | 12 ++++++++++++ .github/workflows/release-builds.yml | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index a54e30a..6f91449 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -22,6 +22,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: @@ -139,6 +145,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml index 052c2f6..0790d8c 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -19,6 +19,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: @@ -87,6 +93,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Java 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: