/* * Copyright 2018-2024 Frederic Thevenet * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.gradle.api.internal.file.copy.CopyAction import org.gradle.api.internal.file.copy.CopyActionProcessingStream import java.nio.file.Files import java.nio.file.Paths import java.nio.file.StandardCopyOption import java.text.SimpleDateFormat import java.time.Duration plugins { id "de.undercouch.download" version "5.6.0" id 'org.kordamp.gradle.markdown' version '2.2.0' id "com.github.ben-manes.versions" version "0.51.0" id "de.marcphilipp.nexus-publish" version "0.4.0" apply false id "signing" } ext.IS_TAG = System.getenv('IS_TAG') != null ? System.getenv('IS_TAG') == "true" : false ext.IS_RELEASE = IS_TAG && !(System.getenv('REPO_TAG_NAME').endsWith('-SNAPSHOT')) ext.IS_BETA = false ext.BINJR_BETA_VERSION = "0.0.0" ext.BINJR_VERSION_STEM = "3.19.0" ext.LINUX_APP_RELEASE = "1" ext.BINJR_VERSION = "${BINJR_VERSION_STEM}${IS_RELEASE ? '' : '-SNAPSHOT'}" ext.BINJR_BUILD_NUMBER = System.getenv('BINJR_BUILD_NUMBER') == null ? ("000") : System.getenv('BINJR_BUILD_NUMBER') ext.GROUP_ID = 'eu.binjr' ext.LICENSE_NAME = 'Apache License, Version 2.0' ext.LICENSE_URL = 'http ://www.apache.org/licenses/LICENSE-2.0.txt' ext.LICENSE_DISTRIBUTION = 'repo' ext.BINJR_COPYRIGHT = "Copyright (c) 2016-2024 Frederic Thevenet" ext.BINJR_DESCRIPTION = "A Time Series Browser" ext.OS_NAME = System.getProperty("os.name").toLowerCase() ext.OS_ARCH = System.getProperty("os.arch") ext.IS_64 = OS_ARCH.toLowerCase().contains("64") ext.BINJR_MAX_HEAP_SIZE = IS_64 ? "4096M" : "2048M" ext.IS_MONOCLE = false ext.IS_MAC = OS_NAME.contains("mac") || OS_NAME.contains("darwin") ext.IS_WINDOWS = OS_NAME.contains("windows") ext.IS_LINUX = OS_NAME.contains("linux") ext.OS_FAMILY = IS_MAC ? 'mac' : IS_WINDOWS ? 'windows' : IS_LINUX ? 'linux' : 'unsupported' ext.JDK_HOME = System.getProperty("java.home") ext.OPENJFX_VERSION = "22.0.1" ext.USE_BUILD_JDK_IN_BUNDLE = false ext.BUNDLE_JDK_VERSION = "jdk-22.0.1+8" ext.OPENJFX_VERSION_STEM = OPENJFX_VERSION.replaceAll("-ea\\+[0-9]+", "") ext.OPENJFX_PLATEFORM_CLASSIFIER = craftPlatformClassifier() ext.DL_CACHE_PATH = System.getProperty("java.io.tmpdir") + "/gradle_dl_cache/" ext.IS_JAVAFX_BUNDLED = ModuleLayer.boot().findModule("javafx.controls").isPresent() ext.ADDITIONAL_JMOD_PATH = IS_JAVAFX_BUNDLED ? "" : "${File.pathSeparator}${buildDir}/jmods/javafx-jmods-${OPENJFX_VERSION_STEM}" ext.JLINK_ADD_MODULES = "javafx.controls," + "javafx.fxml," + "javafx.swing," + "java.base," + "java.prefs," + "java.sql," + "java.xml," + "java.management," + "java.net.http," + "java.rmi," + "jdk.localedata," + "java.management.rmi," + "jdk.management.agent," + "jdk.security.auth,jdk.management," + "jdk.management.jfr," + "jdk.zipfs," + "jdk.unsupported.desktop," + "jdk.crypto.ec," + "jdk.crypto.cryptoki" + "${IS_WINDOWS ? ",jdk.crypto.mscapi" : ""}" ext.DISTRIBUTION_NAME = "${project.name}-${BINJR_VERSION}_${OS_FAMILY}-${OS_ARCH}" ext.APP_IMAGE_ROOT = "${buildDir}/app_image/${DISTRIBUTION_NAME}" ext.APP_IMAGE_PATH = IS_WINDOWS ? "${APP_IMAGE_ROOT}" : "${APP_IMAGE_ROOT}/${BINJR_VERSION}" ext.WIX_HOME = System.getenv("WIX") ext.WIX_HEAT_HOME = System.getenv("WIX_HEAT_HOME") ext.ARTIFACTS_ROOT_PATH = "${buildDir}/artifacts/" ext.ARTIFACTS_PATH_ZIP = file("${ARTIFACTS_ROOT_PATH}/zip/") ext.ARTIFACTS_PATH_MSI = file("${ARTIFACTS_ROOT_PATH}/msi/") ext.ARTIFACTS_PATH_DMG = file("${ARTIFACTS_ROOT_PATH}/dmg/") ext.ARTIFACTS_PATH_PKG = file("${ARTIFACTS_ROOT_PATH}/pkg/") ext.ARTIFACTS_PATH_RPM = file("${ARTIFACTS_ROOT_PATH}/rpm/") ext.ARTIFACTS_PATH_DEB = file("${ARTIFACTS_ROOT_PATH}/deb/") ext.ARTIFACTS_PATH_TGZ = file("${ARTIFACTS_ROOT_PATH}/tgz/") ext."signing.keyId" = System.getenv('GPG_KEY_NAME') ext."signing.secretKeyRingFile" = System.getenv('GPG_KEYRING_PATH') ext."signing.password" = System.getenv('GPG_PASSPHRASE') System.out.println("Building version: ${BINJR_VERSION}") System.out.println("Is tag: ${IS_TAG}") System.out.println("Is release: ${IS_RELEASE}") if (IS_TAG && System.getenv('REPO_TAG_NAME') != "v${BINJR_VERSION}") { throw new GradleException("Tag name [${System.getenv('REPO_TAG_NAME')}] does not match version [${BINJR_VERSION}]") } configure(subprojects) { if (project == project(':binjr-app')) apply plugin: 'application' else apply plugin: 'java-library' apply plugin: "de.marcphilipp.nexus-publish" apply plugin: "signing" group GROUP_ID version BINJR_VERSION sourceCompatibility = 21 targetCompatibility = 21 description BINJR_DESCRIPTION compileJava.options.encoding = 'UTF-8' if (project != project(':binjr-app')) { project.javadoc { options.encoding = 'UTF-8' options.tags = ["XmlJavaTypeAdapter", "XmlJavaTypeAdapters"] } task javadocJar(type: Jar) { archiveClassifier = 'javadoc' from javadoc } task sourcesJar(type: Jar) { archiveClassifier = 'sources' from sourceSets.main.allSource } dependencies { testImplementation('org.junit.jupiter:junit-jupiter-api:5.10.2') testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.10.2') compileOnly "org.openjfx:javafx-base:$OPENJFX_VERSION:$OPENJFX_PLATEFORM_CLASSIFIER" compileOnly "org.openjfx:javafx-graphics:$OPENJFX_VERSION:$OPENJFX_PLATEFORM_CLASSIFIER" compileOnly "org.openjfx:javafx-controls:$OPENJFX_VERSION:$OPENJFX_PLATEFORM_CLASSIFIER" compileOnly "org.openjfx:javafx-fxml:$OPENJFX_VERSION:$OPENJFX_PLATEFORM_CLASSIFIER" compileOnly "org.openjfx:javafx-swing:$OPENJFX_VERSION:$OPENJFX_PLATEFORM_CLASSIFIER" } } repositories { // mavenLocal() mavenCentral() if (!IS_RELEASE) { // maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } // maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots' } // maven { url 'https://repository.apache.org/snapshots/' } } } publishing { publications { mavenJava(MavenPublication) { artifactId = project.name if (project != project(':binjr-app')) { from components.java artifact sourcesJar artifact javadocJar } pom { name = project.name description = 'A Time Series Data Browser' url = 'https://binjr.eu' if (project == project(':binjr-app')) { packaging = 'pom' } else { packaging = 'jar' } licenses { license { name = 'The Apache License, Version 2.0' url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' distribution = 'repo' } } developers { developer { id = 'fthevenet' name = 'Frederic Thevenet' } } scm { connection = 'scm:git:https://github.com/binjr/binjr.git' developerConnection = 'scm:git:https://github.com/binjr/binjr.git' url = 'https://github.com/binjr/binjr' } if (project == project(':binjr-app')) { withXml { Node pluginNode = asNode().appendNode('build') .appendNode('plugins') .appendNode('plugin') pluginNode.appendNode('groupId', 'org.codehaus.mojo') pluginNode.appendNode('artifactId', 'exec-maven-plugin') pluginNode.appendNode('version', '1.2.1') pluginNode.appendNode('executions') .appendNode('execution') .appendNode('goals') .appendNode('goal', 'java') pluginNode.appendNode('configuration') .appendNode('mainClass', 'eu.binjr.core.Bootstrap') Node depsNode = asNode().appendNode('dependencies') project.configurations.runtimeClasspath.each { if (it.name.startsWith('binjr')) { Node depNode = depsNode.appendNode('dependency') depNode.appendNode('groupId', GROUP_ID) depNode.appendNode('artifactId', it.name.replace("-${BINJR_VERSION}.jar", "")) depNode.appendNode('version', BINJR_VERSION) } } } } } } } } signing { required { IS_RELEASE && gradle.taskGraph.hasTask("publishArtifacts") } sign publishing.publications.mavenJava } tasks.withType(Sign) { onlyIf { IS_RELEASE } } nexusPublishing { repositories { sonatype { username = System.getenv('OSSRH_TOKEN_USERNAME') password = System.getenv('OSSRH_TOKEN_PASSWORD') connectTimeout = Duration.ofSeconds(300) clientTimeout = Duration.ofSeconds(300) } } } } task publishArtifacts(dependsOn: subprojects.publishToSonatype) { doLast { System.out.println("Done publishing artifacts from subprojects.") } } task copyAppLibs(type: Copy) { into "$APP_IMAGE_PATH/libs" from(project(":binjr-core").configurations.runtimeClasspath) { exclude "javafx-*.jar" } from project(":binjr-adapter-jrds").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-csv").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-jfr").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-rrd4j").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-netdata").configurations.runtimeClasspath { exclude "javafx-*.jar" } // from project(":binjr-adapter-text").configurations.runtimeClasspath { // exclude "javafx-*.jar" // } from project(":binjr-adapter-logs").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-core").jar } task copyPluginLibs(type: Copy) { into IS_MAC ? "$APP_IMAGE_PATH/libs" : "$APP_IMAGE_PATH/plugins" from project(":binjr-adapter-jrds").jar from project(":binjr-adapter-csv").jar from project(":binjr-adapter-jfr").jar from project(":binjr-adapter-rrd4j").jar from project(":binjr-adapter-netdata").jar // from project(":binjr-adapter-text").jar from project(":binjr-adapter-logs").jar } task copyJpackageInputLibs(type: Copy) { into "${buildDir}/tmp/input" from(project(":binjr-core").configurations.runtimeClasspath) { exclude "javafx-*.jar" } from project(":binjr-adapter-jrds").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-jfr").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-csv").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-rrd4j").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-adapter-netdata").configurations.runtimeClasspath { exclude "javafx-*.jar" } // from project(":binjr-adapter-text").configurations.runtimeClasspath { // exclude "javafx-*.jar" // } from project(":binjr-adapter-logs").configurations.runtimeClasspath { exclude "javafx-*.jar" } from project(":binjr-core").jar from project(":binjr-adapter-jrds").jar from project(":binjr-adapter-jfr").jar from project(":binjr-adapter-csv").jar from project(":binjr-adapter-rrd4j").jar from project(":binjr-adapter-netdata").jar // from project(":binjr-adapter-text").jar from project(":binjr-adapter-logs").jar } task copyPlatformSpecific(type: Copy) { into APP_IMAGE_PATH from "${projectDir}/distribution/platforms/${OS_FAMILY}" } task copyResources(type: Copy) { into "$APP_IMAGE_PATH/resources" from "${projectDir}/distribution/resources" } task expandMdTemplates(type: Copy) { from "${projectDir}/distribution/templates" into "${buildDir}/tmp/expanded" filteringCharset = 'UTF-8' def changeHistory = new File("${project.projectDir}/CHANGELOG.md").getText("UTF-8") def currentChanges = new File("${project.projectDir}/UNRELEASED.md").getText("UTF-8") expand(["version" : "$BINJR_VERSION", "releaseDate" : "${new SimpleDateFormat("EEE, d MMM yyyy").format(new Date())}", "changeHistory" : "$changeHistory", "currentChanges": "$currentChanges", "tagName" : "v${BINJR_VERSION}" ]) } task copyInfo(type: Copy, dependsOn: expandMdTemplates) { from { ["${buildDir}/tmp/expanded/CHANGELOG.md", "${buildDir}/tmp/expanded/LICENSE.md", "${buildDir}/tmp/expanded/NOTICE.md", "${buildDir}/tmp/expanded/README.md"] } into "${buildDir}/tmp/info" } markdownToHtml.dependsOn(copyInfo) markdownToHtml { sourceDir = file("${buildDir}/tmp/info") outputDir = file("$APP_IMAGE_PATH") doLast { ConfigurableFileTree tree = fileTree(dir: "$APP_IMAGE_PATH") tree.include '**/*.html' tree.each { File file -> String path = file.path File newFile = new File("${APP_IMAGE_PATH}/tmp_${file.name}") newFile << "\n" + "\n" + " " + (file.name - ".html") + "\n" + " \n" + " \n" + "" newFile << file.getText("utf-8") if (!file.name.startsWith("LICENSE")) { newFile << "" } file.delete() newFile.renameTo(path) } } } task downloadOpenJfxModules(type: Download) { onlyIfModified true src craftOpenJfxModsUrl() dest new File(DL_CACHE_PATH, "openjfx-jmods_${OPENJFX_VERSION}.zip") } task downloadJlinkOpenJdk(type: Download) { onlyIfModified true src craftJlinkJdkUrl() dest new File(DL_CACHE_PATH, "openjdk_${BUNDLE_JDK_VERSION}${IS_WINDOWS ? '.zip' : '.tar.gz'}") } task unzipOpenJfxModules(dependsOn: downloadOpenJfxModules, type: Copy) { from zipTree(downloadOpenJfxModules.dest) into "${buildDir}/jmods/" } task unzipJlinkOpenJdk(dependsOn: downloadJlinkOpenJdk, type: Copy) { from zipTree(downloadJlinkOpenJdk.dest) into "${buildDir}/jlinkOpenJDK/" } task untarJlinkOpenJdk(dependsOn: downloadJlinkOpenJdk, type: Copy) { from tarTree(downloadJlinkOpenJdk.dest) into "${buildDir}/jlinkOpenJDK/" } task createRuntimeImage(type: Exec) { if (!IS_JAVAFX_BUNDLED) { dependsOn unzipOpenJfxModules } def jlinkJdkDir if (USE_BUILD_JDK_IN_BUNDLE) { jlinkJdkDir = "${JDK_HOME}" } else { if (IS_WINDOWS) { dependsOn unzipJlinkOpenJdk } else { dependsOn untarJlinkOpenJdk } jlinkJdkDir = "${buildDir}/jlinkOpenJDK/${BUNDLE_JDK_VERSION}${IS_MAC ? '/Contents/Home' : ''}" } workingDir project.projectDir commandLine = [ "${jlinkJdkDir}/bin/jlink", '-p', "${jlinkJdkDir}/jmods${ADDITIONAL_JMOD_PATH}", '--add-modules', JLINK_ADD_MODULES, '--strip-debug', '--no-header-files', '--no-man-pages', "--vm=server", "--compress=zip-6", '--output', "${APP_IMAGE_PATH}/runtime" ] doLast { System.out.println("Application '${project.name}' packaged.") System.out.println(" -> location: ${APP_IMAGE_PATH}/") } } task prepareAppBundle(dependsOn: [copyAppLibs, copyPluginLibs, copyResources, copyPlatformSpecific, markdownToHtml, createRuntimeImage]) { doFirst { mkdir ARTIFACTS_ROOT_PATH } } task listPackageContent(type: Exec, dependsOn: prepareAppBundle) { workingDir APP_IMAGE_PATH commandLine = [ "sh", "-c", "find . -mindepth 1 | sed -n 's@^\\./@@p' > .installed" ] } task packageDistributionZip(type: Zip, dependsOn: prepareAppBundle) { doFirst { Files.copy(Paths.get("${projectDir}/distribution/bundlers/win_zip/binjr.ini"), Paths.get("${APP_IMAGE_PATH}/binjr.ini"), StandardCopyOption.REPLACE_EXISTING) } from APP_IMAGE_ROOT destinationDirectory = ARTIFACTS_PATH_ZIP archiveFileName = "${DISTRIBUTION_NAME}.zip" outputs.dir ARTIFACTS_PATH_ZIP } task packageDistributionTar(type: Exec, dependsOn: [listPackageContent]) { workingDir APP_IMAGE_ROOT commandLine = [ "sh", "-c", "ln -s \"${BINJR_VERSION}/binjr\" \"binjr\" && tar czf \"${ARTIFACTS_PATH_TGZ}/${DISTRIBUTION_NAME}.tar.gz\" \"${BINJR_VERSION}\" \"binjr\"" ] outputs.dir ARTIFACTS_PATH_TGZ } task wixRunHeat(type: Exec, dependsOn: prepareAppBundle) { doFirst { Files.copy(Paths.get("${projectDir}/distribution/bundlers/win_msi/binjr.ini"), Paths.get("${APP_IMAGE_PATH}/binjr.ini"), StandardCopyOption.REPLACE_EXISTING) } workingDir project.projectDir commandLine = [ "${WIX_HEAT_HOME}/heat.exe", "dir", "${APP_IMAGE_PATH}", "-cg", "binjrFiles", "-suid", "-gg", "-scom", "-sreg", "-sfrag", "-srd", "-dr", "APPLICATIONFOLDER", "-var", "var.buildSourceDir", "-out", "${buildDir}/wix/binjrFiles.wxs" ] } //task wixRunCandle(type: Exec, dependsOn: [wixRunHeat]) { // workingDir project.projectDir // commandLine = [ // "${WIX_HOME}/bin/candle.exe", // "-arch", "x64", // "-out", "${buildDir}/wix/obj/", // "${projectDir}/distribution/bundlers/win_msi/binjr.wxs", // "${buildDir}/wix/binjrFiles.wxs", // "-dbinjrVersion=${IS_BETA ? BINJR_BETA_VERSION : BINJR_VERSION_STEM}", // "-dbuildSourceDir=${APP_IMAGE_PATH}", // "-dresourcesDir=${projectDir}/distribution" // ] //} // //task wixRunLight(type: Exec, dependsOn: [wixRunCandle]) { // workingDir project.projectDir // commandLine = [ // "${WIX_HOME}/bin/light.exe", // "-sw", "-sice:ICE38", "-sice:ICE64", // "-out", "${ARTIFACTS_PATH_MSI}/${DISTRIBUTION_NAME}.msi", // "${buildDir}/wix/obj/*.wixobj", // "-ext", "WixUtilExtension", "-ext", "WixUIExtension.dll" // ] // outputs.dir ARTIFACTS_PATH_MSI //} task wixAddUiExt(type: Exec, dependsOn: wixRunHeat) { commandLine = ["wix.exe", "extension", "add", "-g", "WixToolset.UI.wixext"] } task wixAddUtilExt(type: Exec, dependsOn: wixAddUiExt) { commandLine = ["wix.exe", "extension", "add", "-g", "WixToolset.Util.wixext"] } task wixRunBuild(type: Exec, dependsOn: [wixAddUtilExt]) { workingDir project.projectDir commandLine = [ "wix.exe", "build", "-arch", "${getArch()}", "${projectDir}/distribution/bundlers/win_msi/binjr.wxs", "${buildDir}/wix/binjrFiles.wxs", "-ext", "WixToolset.UI.wixext", "-ext", "WixToolset.Util.wixext", "-d", "binjrVersion=${IS_BETA ? BINJR_BETA_VERSION : BINJR_VERSION_STEM}", "-d", "buildSourceDir=${APP_IMAGE_PATH}", "-d", "resourcesDir=${projectDir}/distribution", "-out", "${ARTIFACTS_PATH_MSI}/${DISTRIBUTION_NAME}.msi", "-pdbtype", "none" ] outputs.dir ARTIFACTS_PATH_MSI } task jpackageDmg(type: Exec, dependsOn: [prepareAppBundle, copyJpackageInputLibs]) { workingDir ARTIFACTS_PATH_DMG commandLine = [ "jpackage", "--name", project.name, "--input", "${buildDir}/tmp/input", "--main-jar", "binjr-core-${BINJR_VERSION}.jar", "--main-class", "eu.binjr.core.Bootstrap", "--runtime-image", "${APP_IMAGE_PATH}/runtime", "--type", "dmg", "--copyright", BINJR_COPYRIGHT, "--description", BINJR_DESCRIPTION, "--app-version", "${IS_BETA ? BINJR_BETA_VERSION : BINJR_VERSION_STEM}", "--icon", "${APP_IMAGE_PATH}/resources/icons/binjr.icns", "--file-associations", "${projectDir}/distribution/bundlers/mac_dmg/file-associations.properties", "--arguments", "--packaging=MAC_DMG", "--java-options", "-Xmx${BINJR_MAX_HEAP_SIZE}", "--java-options", "-XX:+UnlockExperimentalVMOptions", "--java-options", "-XX:+UseShenandoahGC", "--java-options", "-XX:ShenandoahGCHeuristics=compact", "--java-options", "-XX:ShenandoahAllocationThreshold=20", "--java-options", "--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED", "--java-options", "--add-exports=javafx.controls/com.sun.javafx.charts=ALL-UNNAMED", "--java-options", "--add-opens=javafx.graphics/javafx.geometry=ALL-UNNAMED", "--java-options", "-Dapple.awt.application.appearance=system" ] doLast { def source = java.nio.file.Path.of("${ARTIFACTS_PATH_DMG}/${project.name}-${IS_BETA ? BINJR_BETA_VERSION : BINJR_VERSION_STEM}.dmg") Files.move(source, source.resolveSibling("${DISTRIBUTION_NAME}.dmg")) } outputs.dir ARTIFACTS_PATH_DMG } task jpackagePkg(type: Exec, dependsOn: [prepareAppBundle, copyJpackageInputLibs]) { workingDir ARTIFACTS_PATH_PKG commandLine = [ "jpackage", "--name", project.name, "--input", "${buildDir}/tmp/input", "--main-jar", "binjr-core-${BINJR_VERSION}.jar", "--main-class", "eu.binjr.core.Bootstrap", "--runtime-image", "${APP_IMAGE_PATH}/runtime", "--type", "pkg", "--copyright", BINJR_COPYRIGHT, "--description", BINJR_DESCRIPTION, "--app-version", "${IS_BETA ? BINJR_BETA_VERSION : BINJR_VERSION_STEM}", "--icon", "${APP_IMAGE_PATH}/resources/icons/binjr.icns", "--file-associations", "${projectDir}/distribution/bundlers/mac_pkg/file-associations.properties", "--arguments", "--packaging=MAC_PKG", "--java-options", "-Xmx${BINJR_MAX_HEAP_SIZE}", "--java-options", "-XX:+UnlockExperimentalVMOptions", "--java-options", "-XX:+UseShenandoahGC", "--java-options", "-XX:ShenandoahGCHeuristics=compact", "--java-options", "-XX:ShenandoahAllocationThreshold=20", "--java-options", "--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED", "--java-options", "--add-exports=javafx.controls/com.sun.javafx.charts=ALL-UNNAMED", "--java-options", "--add-opens=javafx.graphics/javafx.geometry=ALL-UNNAMED", "--java-options", "-Dapple.awt.application.appearance=system" ] doLast { def source = java.nio.file.Path.of("${ARTIFACTS_PATH_PKG}/${project.name}-${IS_BETA ? BINJR_BETA_VERSION : BINJR_VERSION_STEM}.pkg") Files.move(source, source.resolveSibling("${DISTRIBUTION_NAME}.pkg")) } outputs.dir ARTIFACTS_PATH_PKG } task jpackageDeb(type: Exec, dependsOn: [prepareAppBundle, copyJpackageInputLibs]) { workingDir ARTIFACTS_PATH_DEB commandLine = [ "jpackage", "--name", project.name, "--input", "${buildDir}/tmp/input", "--main-jar", "binjr-core-${BINJR_VERSION}.jar", "--main-class", "eu.binjr.core.Bootstrap", "--runtime-image", "${APP_IMAGE_PATH}/runtime", "--type", "deb", "--copyright", BINJR_COPYRIGHT, "--description", BINJR_DESCRIPTION, "--app-version", BINJR_VERSION, "--icon", "${APP_IMAGE_PATH}/resources/icons/binjr.png", "--license-file", "${projectDir}/LICENSE.md", "--file-associations", "${projectDir}/distribution/bundlers/linux_deb/file-associations.properties", "--resource-dir", "${projectDir}/distribution/bundlers/linux_deb/", "--java-options", "-Xmx${BINJR_MAX_HEAP_SIZE}", "--java-options", "-XX:+UnlockExperimentalVMOptions", "--java-options", "-XX:+UseShenandoahGC", "--java-options", "-XX:ShenandoahGCHeuristics=compact", "--java-options", "-XX:ShenandoahAllocationThreshold=20", "--java-options", "--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED", "--java-options", "--add-exports=javafx.controls/com.sun.javafx.charts=ALL-UNNAMED", "--java-options", "--add-opens=javafx.graphics/javafx.geometry=ALL-UNNAMED", "--arguments", "--system-plugins-path=/opt/binjr/plugins", "--arguments", "--packaging=LINUX_DEB", "--linux-package-name", "binjr", "--linux-deb-maintainer", "binjr@free.fr", "--linux-app-category", "Utility", "--linux-app-release", LINUX_APP_RELEASE, "--linux-menu-group", "Utility", "--linux-rpm-license-type", "Apache-2.0", "--linux-shortcut", "--temp", "${buildDir}/tmp/apt", "--verbose" ] doLast { def source = java.nio.file.Path.of("${ARTIFACTS_PATH_DEB}/${project.name}_${BINJR_VERSION}-1_${OS_ARCH}.deb") Files.move(source, source.resolveSibling("${DISTRIBUTION_NAME}.deb")) } outputs.dir ARTIFACTS_PATH_DEB } task jpackageRpm(type: Exec, dependsOn: [prepareAppBundle, copyJpackageInputLibs]) { workingDir ARTIFACTS_PATH_RPM commandLine = [ "jpackage", "--name", project.name, "--input", "${buildDir}/tmp/input", "--main-jar", "binjr-core-${BINJR_VERSION}.jar", "--main-class", "eu.binjr.core.Bootstrap", "--runtime-image", "${APP_IMAGE_PATH}/runtime", "--type", "rpm", "--copyright", BINJR_COPYRIGHT, "--description", BINJR_DESCRIPTION, "--app-version", BINJR_VERSION.replace("-", "."), "--icon", "${APP_IMAGE_PATH}/resources/icons/binjr.png", "--license-file", "${projectDir}/LICENSE.md", "--file-associations", "${projectDir}/distribution/bundlers/linux_rpm/file-associations.properties", "--resource-dir", "${projectDir}/distribution/bundlers/linux_rpm/", "--java-options", "-Xmx${BINJR_MAX_HEAP_SIZE}", "--java-options", "-XX:+UnlockExperimentalVMOptions", "--java-options", "-XX:+UseShenandoahGC", "--java-options", "-XX:ShenandoahGCHeuristics=compact", "--java-options", "-XX:ShenandoahAllocationThreshold=20", "--java-options", "--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED", "--java-options", "--add-exports=javafx.controls/com.sun.javafx.charts=ALL-UNNAMED", "--java-options", "--add-opens=javafx.graphics/javafx.geometry=ALL-UNNAMED", "--arguments", "--system-plugins-path=/opt/binjr/plugins", "--arguments", "--packaging=LINUX_RPM", "--linux-package-name", "binjr", "--linux-app-category", "Utility", "--linux-app-release", LINUX_APP_RELEASE, "--linux-menu-group", "Utility", "--linux-rpm-license-type", "Apache-2.0", "--linux-shortcut", "--temp", "${buildDir}/tmp/rpm", "--verbose" ] doLast { def source = java.nio.file.Path.of("${ARTIFACTS_PATH_RPM}/${project.name}-${BINJR_VERSION.replace("-", ".")}-1.x86_64.rpm") Files.move(source, source.resolveSibling("${DISTRIBUTION_NAME}.rpm")) } outputs.dir ARTIFACTS_PATH_RPM } task packageAsZip(type: WrapTaskForSigning, dependsOn: [packageDistributionZip]) { from "${ARTIFACTS_PATH_ZIP}/${DISTRIBUTION_NAME}.zip" destinationDirectory = ARTIFACTS_PATH_ZIP archiveFileName = "${DISTRIBUTION_NAME}.zip" } task packageAsMsi(type: WrapTaskForSigning, dependsOn: [wixRunBuild]) { from "${ARTIFACTS_PATH_MSI}/${DISTRIBUTION_NAME}.msi" destinationDirectory = ARTIFACTS_PATH_MSI archiveFileName = "${DISTRIBUTION_NAME}.msi" } task packageAsDmg(type: WrapTaskForSigning, dependsOn: [jpackageDmg]) { from "${ARTIFACTS_PATH_DMG}/${DISTRIBUTION_NAME}.dmg" destinationDirectory = ARTIFACTS_PATH_DMG archiveFileName = "${DISTRIBUTION_NAME}.dmg" } task packageAsPkg(type: WrapTaskForSigning, dependsOn: [jpackagePkg]) { from "${ARTIFACTS_PATH_PKG}/${DISTRIBUTION_NAME}.pkg" destinationDirectory = ARTIFACTS_PATH_PKG archiveFileName = "${DISTRIBUTION_NAME}.pkg" } task packageAsTarGz(type: WrapTaskForSigning, dependsOn: [packageDistributionTar]) { from "${ARTIFACTS_PATH_TGZ}/${DISTRIBUTION_NAME}.tar.gz" destinationDirectory = ARTIFACTS_PATH_TGZ archiveFileName = "${DISTRIBUTION_NAME}.tar.gz" } task packageAsRpm(type: WrapTaskForSigning, dependsOn: [jpackageRpm]) { from "${ARTIFACTS_PATH_RPM}/${DISTRIBUTION_NAME}.rpm" destinationDirectory = ARTIFACTS_PATH_RPM archiveFileName = "${DISTRIBUTION_NAME}.rpm" } task packageAsDeb(type: WrapTaskForSigning, dependsOn: [jpackageDeb]) { from "${ARTIFACTS_PATH_DEB}/${DISTRIBUTION_NAME}.deb" destinationDirectory = ARTIFACTS_PATH_DEB archiveFileName = "${DISTRIBUTION_NAME}.deb" } signing { sign packageAsZip sign packageAsMsi sign packageAsPkg sign packageAsTarGz sign packageAsRpm sign packageAsDeb } task packageDistribution() { if (IS_WINDOWS) { finalizedBy(packageAsMsi, packageAsZip) } else if (IS_MAC) { finalizedBy(packageAsPkg, packageAsTarGz) } else { finalizedBy(packageAsTarGz, packageAsDeb, packageAsRpm) } } task signPackageDistribution() { if (IS_WINDOWS) { finalizedBy(signPackageAsMsi, signPackageAsZip) } else if (IS_MAC) { finalizedBy(signPackageAsPkg, signPackageAsTarGz) } else { finalizedBy(signPackageAsTarGz, signPackageAsDeb, signPackageAsRpm) } } def isNonStable = { String version -> // Ignore javafx early access and glassfish beta def regex = /(?i)^[0-9,.v-]+\-((ea)|(rc)|(alpha)|(b)|(m))[-\+]*[0-9.]+$/ return (version ==~ regex) } def craftPlatformClassifier() { def classifier if (IS_MAC) { classifier = "mac" if (OS_ARCH == "aarch64") { classifier += "-aarch64" } } else if (IS_LINUX) { classifier = "linux" if (OS_ARCH == "aarch64") { classifier += "-aarch64" } else if (OS_ARCH == "aarch32" || OS_ARCH == "arm32") { classifier += "-arm32" } } else if (IS_WINDOWS) { classifier = "win" if (OS_ARCH == "x86") { classifier += "-x86" } } if (IS_MONOCLE) { classifier += "-monocle" } return classifier } def craftJlinkJdkUrl() { def platform switch (OS_FAMILY) { case "windows": platform = "windows" break case "linux": platform = "linux" break case "mac": platform = "mac" break default: throw new Exception("Cannot download OpenJFX modules for unsupported platform: ${OS_FAMILY} - ${OS_ARCH}") } def arch = getArch() return "https://api.adoptium.net/v3/binary/version/${BUNDLE_JDK_VERSION}/${platform}/${arch}/jdk/hotspot/normal/eclipse" } def craftOpenJfxModsUrl() { def platform switch (OS_FAMILY) { case "windows": platform = "windows" break case "linux": platform = "linux" break case "mac": platform = "osx" break default: throw new Exception("Cannot download OpenJFX modules for unsupported platform: ${OS_FAMILY} - ${OS_ARCH}") } def arch = getArch() return "https://download2.gluonhq.com/openjfx/${OPENJFX_VERSION_STEM}/openjfx-${OPENJFX_VERSION}_${platform}-${arch}_bin-jmods.zip" } def getArch() { def arch switch (OS_ARCH) { case "amd64": case "x86_64": arch = "x64" break case "x86": arch = "x86" break case "aarch64": arch = "aarch64" break default: throw new Exception("Cannot download OpenJFX modules for unsupported platform: ${OS_FAMILY} - ${OS_ARCH}") } return arch } dependencyUpdates { rejectVersionIf { isNonStable(it.candidate.version) } } /** * This class is a no-op copy task whose purpose is to allow using the * standard gradle signing plugin to sign any arbitrary file. * The idea is to piggy-back on the existing support for signing * of tasks extending AbstractArchiveTask; to use it, simply declare a * task of that type and use the path to the file to be signed both as * the source and target of the archive. * NB: No copy/move/archiving will actually take place. */ class WrapTaskForSigning extends AbstractArchiveTask { @Override protected CopyAction createCopyAction() { return new noopCopyAction(); } class noopCopyAction implements CopyAction { @Override WorkResult execute(CopyActionProcessingStream stream) { return WorkResults.didWork(true); } } }