From d55823ecb1f17b974e45c2873c03dc11f7078314 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 2 Apr 2025 13:37:19 +0100 Subject: [PATCH] MacOS Installer for `x86_64` Distributions (#3269) - Updated `jpackage` task to create an additional installer for MacOS with Intel (x86_64) chips - Created tasks to download zulu-jre-17 to a temp folder to use when building x86_64 installer and then delete afterwards Closes #1531 --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [x] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [x] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [x] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [x] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --- .github/workflows/multiOSReleases.yml | 1 + build.gradle | 144 ++++++++++++++++++++++---- 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index 12c36510f..6ddf64c23 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -180,6 +180,7 @@ jobs: mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.version }}.exe" "./binaries/Stirling-PDF-win-installer.exe" elif [ "${{ matrix.os }}" = "macos-latest" ]; then mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-installer.dmg" + mv "./build/jpackage/Stirling-PDF-x86_64-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-x86_64-installer.dmg" else mv "./build/jpackage/stirling-pdf_${{ needs.read_versions.outputs.version }}-1_amd64.deb" "./binaries/Stirling-PDF-linux-installer.deb" fi diff --git a/build.gradle b/build.gradle index 8a9c2f69a..a8d2e19b4 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,9 @@ plugins { } import com.github.jk1.license.render.* +import org.gradle.internal.os.OperatingSystem +import java.nio.file.Files +import java.time.Year ext { springBootVersion = "3.4.4" @@ -22,6 +25,7 @@ ext { bouncycastleVersion = "1.80" springSecuritySamlVersion = "6.4.4" openSamlVersion = "4.3.2" + tempJrePath = null } group = "stirling.software" @@ -102,8 +106,8 @@ openApi { } //0.11.5 to 2024.11.5 -def getMacVersion(String version) { - def currentYear = java.time.Year.now().getValue() +static def getMacVersion(String version) { + def currentYear = Year.now().getValue() def versionParts = version.split("\\.", 2) return "${currentYear}.${versionParts.length > 1 ? versionParts[1] : versionParts[0]}" } @@ -114,6 +118,7 @@ jpackage { mainJar = "Stirling-PDF-${project.version}.jar" appName = "Stirling-PDF" appVersion = project.version +// appVersion = "2005.45.1" vendor = "Stirling-Software" appDescription = "Stirling PDF - Your Local PDF Editor" icon = "src/main/resources/static/favicon.ico" @@ -160,22 +165,22 @@ jpackage { icon = "src/main/resources/static/favicon.icns" type = "dmg" macPackageIdentifier = "com.stirling.software.pdf" - macPackageName = "Stirling-PDF" + macPackageName = "Stirling-PDF_aarch64" macAppCategory = "public.app-category.productivity" macSign = false // Enable signing macAppStore = false // Not targeting App Store initially - - //installDir = "Applications" - - // Add license and other documentation to DMG - /*macDmgContent = [ - "README.md", - "LICENSE", - "CHANGELOG.md" - ]*/ - - // Enable Mac-specific entitlements - //macEntitlements = "entitlements.plist" // You'll need to create this file +// +// //installDir = "Applications" +// +// // Add license and other documentation to DMG +// /*macDmgContent = [ +// "README.md", +// "LICENSE", +// "CHANGELOG.md" +// ]*/ +// +// // Enable Mac-specific entitlements +// //macEntitlements = "entitlements.plist" // You'll need to create this file } // Linux-specific configuration @@ -221,6 +226,107 @@ jpackage { licenseFile = "LICENSE" } +tasks.register('jpackageMacX64') { + group = 'distribution' + description = 'Packages app for MacOS x86_64' + + if (OperatingSystem.current().isMacOsX()) { + println "MacOS detected. Downloading temp JRE." + dependsOn("downloadTempJre") + } else { + return + } + + doLast { + def jrePath = project.ext.tempJrePath + + if (!jrePath) { + throw new GradleException("JRE path not found.") + } + + def outputStream = new ByteArrayOutputStream() + def errorStream = new ByteArrayOutputStream() + + def result = exec { + commandLine 'jpackage', + '--type', 'dmg', + '--name', 'Stirling-PDF-x86_64', + '--input', 'build/libs', + '--main-jar', "Stirling-PDF-${project.version}.jar", + '--main-class', 'stirling.software.SPDF.SPDFApplication', + '--runtime-image', file(jrePath + "/zulu-17.jre/Contents/Home"), + '--dest', 'build/jpackage', + '--icon', 'src/main/resources/static/favicon.icns', + '--app-version', getMacVersion(project.version.toString()), + '--mac-package-name', 'Stirling-PDF', + '--mac-package-identifier', 'com.stirling.software.pdf', + '--mac-app-category', 'public.app-category.productivity' + standardOutput = outputStream + errorOutput = errorStream + ignoreExitValue = true + } + + def stdout = outputStream.toString("UTF-8") + def stderr = errorStream.toString("UTF-8") + + if (!stdout.isBlank()) { + println "๐Ÿ“ jpackage stdout:\n$stdout" + } + + if (result.exitValue != 0) { + throw new GradleException("โŒ jpackage failed with exit code ${result.exitValue}.\n\n$stderr") + } + } +} + +jpackage.finalizedBy(jpackageMacX64) + +tasks.register('downloadTempJre') { + group = 'distribution' + description = 'Downloads and extracts a temporary JRE' + + doLast { + try { + def jreUrl = 'https://cdn.azul.com/zulu/bin/zulu17.56.15-ca-jre17.0.14-macosx_x64.tar.gz' + def tmpDir = Files.createTempDirectory('zulu-jre').toFile() + def jreArchive = new File(tmpDir, 'jre.tar.gz') + def jreDir = new File(tmpDir, 'jre') + + println "๐Ÿ”ฝ Downloading JRE to $jreArchive..." + jreArchive.withOutputStream { out -> + new URI(jreUrl).toURL().withInputStream { from -> out << from } + } + + println "๐Ÿ“ฆ Extracting JRE to $jreDir..." + jreDir.mkdirs() + providers.exec { + commandLine 'tar', '-xzf', jreArchive.absolutePath, '-C', jreDir.absolutePath, '--strip-components=1' + }.result.get() + + println "โœ… JRE ready at: $jreDir" + ext.tempJrePath = jreDir.absolutePath + project.ext.tempJrePath = jreDir.absolutePath + } catch (Exception e) { + println "Failed to download JRE. ${e.getLocalizedMessage()}" + cleanTempJre + } + } +} + +tasks.register('cleanTempJre') { + dependsOn('jpackageMacX64') + group = 'distribution' + description = 'Deletes the temporary JRE' + + doLast { + def path = project.ext.tempJrePath + + if (path && new File("$path").exists()) { + println "๐Ÿงน Cleaning up temporary JRE: $path" + new File("$path").parentFile.deleteDir() + } + } +} launch4j { icon = "${projectDir}/src/main/resources/static/favicon.ico" @@ -328,13 +434,13 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion" implementation 'com.posthog.java:posthog:1.2.0' implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' - + if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { - + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' - + implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion" implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.3.RELEASE" implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" @@ -459,12 +565,12 @@ jar { attributes "Implementation-Title": "Stirling-PDF", "Implementation-Version": project.version } - } tasks.named("test") { useJUnitPlatform() } + task printVersion { doLast { println project.version