Added Jlink logic to actions

This commit is contained in:
Connor Yoh 2025-07-08 10:20:21 +01:00
parent 5b4f377972
commit 73c04fe59b
3 changed files with 178 additions and 19 deletions

View File

@ -19,11 +19,13 @@ This directory contains GitHub Actions workflows for building Tauri desktop appl
- **Linux**: x86_64 (deb and AppImage)
**Features**:
- Builds Java backend first
- Builds Java backend with custom JRE using JLink
- Creates self-contained applications (no Java installation required)
- Installs all dependencies
- Creates signed artifacts (if signing keys are configured)
- Validates all artifacts are created successfully
- Can create GitHub releases (when not in test mode)
- Optimized runtime with only required Java modules
### 2. `tauri-test.yml` - Test Workflow
@ -35,9 +37,10 @@ This directory contains GitHub Actions workflows for building Tauri desktop appl
**Features**:
- Allows testing specific platforms or all platforms
- Validates build artifacts are created
- Checks artifact sizes
- Validates build artifacts are created with custom JRE
- Checks artifact sizes and runtime optimization
- Reports results without creating releases
- Caches JLink runtime for faster subsequent builds
## Usage
@ -135,6 +138,25 @@ Both workflows include comprehensive validation:
2. **Artifact Inspection**: Download artifacts to verify contents
3. **Local Testing**: Test builds locally before running workflows
## JLink Integration Benefits
The workflows now use JLink to create custom Java runtimes:
### **Self-Contained Applications**
- **No Java Required**: Users don't need Java installed
- **Consistent Runtime**: Same Java version across all deployments
- **Smaller Size**: Only includes needed Java modules (~30-50MB vs full JRE)
### **Security & Performance**
- **Minimal Attack Surface**: Only required modules included
- **Faster Startup**: Optimized runtime with stripped debug info
- **Better Compression**: JLink level 2 compression reduces size
### **Module Analysis**
- **Automatic Detection**: Uses `jdeps` to analyze JAR dependencies
- **Fallback Safety**: Predefined module list if analysis fails
- **Platform Optimized**: Different modules per platform if needed
## Integration with Existing Workflows
These workflows are designed to complement the existing build system:
@ -142,6 +164,7 @@ These workflows are designed to complement the existing build system:
- Uses same JDK and Gradle setup as `build.yml`
- Follows same security practices as `multiOSReleases.yml`
- Compatible with existing release processes
- Integrates JLink logic from `build-tauri-jlink.sh/bat` scripts
## Next Steps

View File

@ -91,17 +91,90 @@ jobs:
with:
workspaces: './frontend/src-tauri -> target'
- name: Cache JLink runtime
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
with:
path: ./frontend/src-tauri/runtime/jre
key: jlink-runtime-${{ runner.os }}-jdk21-${{ hashFiles('stirling-pdf/build.gradle') }}
restore-keys: |
jlink-runtime-${{ runner.os }}-jdk21-
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "21"
distribution: "temurin"
- name: Build Java backend
- name: Build Java backend with JLink
working-directory: ./
shell: bash
run: |
chmod +x ./gradlew
./gradlew clean build -x test
echo "🔧 Building Stirling-PDF JAR..."
./gradlew clean bootJar --no-daemon
# Find the built JAR
STIRLING_JAR=$(ls stirling-pdf/build/libs/Stirling-PDF-*.jar | head -n 1)
echo "✅ Built JAR: $STIRLING_JAR"
# Create Tauri directories
mkdir -p ./frontend/src-tauri/libs
mkdir -p ./frontend/src-tauri/runtime
# Copy JAR to Tauri libs
cp "$STIRLING_JAR" ./frontend/src-tauri/libs/
echo "✅ JAR copied to Tauri libs"
# Analyze JAR dependencies for jlink modules
echo "🔍 Analyzing JAR dependencies..."
if command -v jdeps &> /dev/null; then
DETECTED_MODULES=$(jdeps --print-module-deps --ignore-missing-deps "$STIRLING_JAR" 2>/dev/null || echo "")
if [ -n "$DETECTED_MODULES" ]; then
echo "📋 jdeps detected modules: $DETECTED_MODULES"
MODULES="$DETECTED_MODULES,java.compiler,java.instrument,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.transaction.xa,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
else
echo "⚠️ jdeps analysis failed, using predefined modules"
MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
fi
else
echo "⚠️ jdeps not available, using predefined modules"
MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
fi
# Create custom JRE with jlink (if not cached)
if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then
echo "🔧 Creating custom JRE with jlink..."
echo "📋 Using modules: $MODULES"
# Create the custom JRE
jlink \
--add-modules "$MODULES" \
--strip-debug \
--compress=2 \
--no-header-files \
--no-man-pages \
--output ./frontend/src-tauri/runtime/jre
if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then
echo "❌ Failed to create JLink runtime"
exit 1
fi
else
echo "✅ Using cached JLink runtime"
fi
# Test the bundled runtime
if [ -f "./frontend/src-tauri/runtime/jre/bin/java" ]; then
RUNTIME_VERSION=$(./frontend/src-tauri/runtime/jre/bin/java --version 2>&1 | head -n 1)
echo "✅ Custom JRE created successfully: $RUNTIME_VERSION"
else
echo "❌ Custom JRE executable not found"
exit 1
fi
# Calculate runtime size
RUNTIME_SIZE=$(du -sh ./frontend/src-tauri/runtime/jre | cut -f1)
echo "📊 Custom JRE size: $RUNTIME_SIZE"
env:
DISABLE_ADDITIONAL_FEATURES: true
@ -109,11 +182,6 @@ jobs:
working-directory: ./frontend
run: npm ci
- name: Copy backend JAR to Tauri resources
run: |
mkdir -p ./frontend/src-tauri/libs
cp ./stirling-pdf/build/libs/stirling-pdf-*.jar ./frontend/src-tauri/libs
- name: Build Tauri app
uses: tauri-apps/tauri-action@6fdd37473788d5a2b4dd80e7ccc0b3c7fe8a5bcd # v0.5.7
env:

View File

@ -56,12 +56,12 @@ jobs:
echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
;;
*)
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"ubuntu-20.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
;;
esac
else
# For PR/push events, test all platforms
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"ubuntu-20.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
fi
test-build:
@ -103,17 +103,90 @@ jobs:
with:
workspaces: './frontend/src-tauri -> target'
- name: Cache JLink runtime
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
with:
path: ./frontend/src-tauri/runtime/jre
key: jlink-runtime-${{ runner.os }}-jdk21-${{ hashFiles('stirling-pdf/build.gradle') }}
restore-keys: |
jlink-runtime-${{ runner.os }}-jdk21-
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "21"
distribution: "temurin"
- name: Build Java backend
- name: Build Java backend with JLink
working-directory: ./
shell: bash
run: |
chmod +x ./gradlew
./gradlew clean build -x test
echo "🔧 Building Stirling-PDF JAR..."
./gradlew clean bootJar --no-daemon
# Find the built JAR
STIRLING_JAR=$(ls stirling-pdf/build/libs/Stirling-PDF-*.jar | head -n 1)
echo "✅ Built JAR: $STIRLING_JAR"
# Create Tauri directories
mkdir -p ./frontend/src-tauri/libs
mkdir -p ./frontend/src-tauri/runtime
# Copy JAR to Tauri libs
cp "$STIRLING_JAR" ./frontend/src-tauri/libs/
echo "✅ JAR copied to Tauri libs"
# Analyze JAR dependencies for jlink modules
echo "🔍 Analyzing JAR dependencies..."
if command -v jdeps &> /dev/null; then
DETECTED_MODULES=$(jdeps --print-module-deps --ignore-missing-deps "$STIRLING_JAR" 2>/dev/null || echo "")
if [ -n "$DETECTED_MODULES" ]; then
echo "📋 jdeps detected modules: $DETECTED_MODULES"
MODULES="$DETECTED_MODULES,java.compiler,java.instrument,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.transaction.xa,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
else
echo "⚠️ jdeps analysis failed, using predefined modules"
MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
fi
else
echo "⚠️ jdeps not available, using predefined modules"
MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported"
fi
# Create custom JRE with jlink (if not cached)
if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then
echo "🔧 Creating custom JRE with jlink..."
echo "📋 Using modules: $MODULES"
# Create the custom JRE
jlink \
--add-modules "$MODULES" \
--strip-debug \
--compress=2 \
--no-header-files \
--no-man-pages \
--output ./frontend/src-tauri/runtime/jre
if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then
echo "❌ Failed to create JLink runtime"
exit 1
fi
else
echo "✅ Using cached JLink runtime"
fi
# Test the bundled runtime
if [ -f "./frontend/src-tauri/runtime/jre/bin/java" ]; then
RUNTIME_VERSION=$(./frontend/src-tauri/runtime/jre/bin/java --version 2>&1 | head -n 1)
echo "✅ Custom JRE created successfully: $RUNTIME_VERSION"
else
echo "❌ Custom JRE executable not found"
exit 1
fi
# Calculate runtime size
RUNTIME_SIZE=$(du -sh ./frontend/src-tauri/runtime/jre | cut -f1)
echo "📊 Custom JRE size: $RUNTIME_SIZE"
env:
DISABLE_ADDITIONAL_FEATURES: true
@ -121,11 +194,6 @@ jobs:
working-directory: ./frontend
run: npm ci
- name: Copy backend JAR to Tauri resources
run: |
mkdir -p ./frontend/src-tauri/libs
cp ./stirling-pdf/build/libs/stirling-pdf-*.jar ./frontend/src-tauri/libs
- name: Build Tauri app (test mode)
uses: tauri-apps/tauri-action@v0.5
env: