build.ps1 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. Param(
  2. [Parameter(Mandatory, HelpMessage="Please provide a name for the app")][string] $AppName,
  3. [Parameter(Mandatory, HelpMessage="Please provide the glob pattern to identify the main jar")][string] $MainJarGlob,
  4. [Parameter(Mandatory, HelpMessage="Please provide the module- and main class path to start the app")][string] $ModuleAndMainClass,
  5. [Parameter(Mandatory, HelpMessage="Please provide the windows upgrade uuid for the installer")][string] $UpgradeUUID,
  6. [Parameter(Mandatory, HelpMessage="Please provide the name of the vendor")][string] $Vendor,
  7. [Parameter(Mandatory, HelpMessage="Please provide the starting year for the copyright notice")][int] $CopyrightStartYear,
  8. [Parameter(Mandatory, HelpMessage="Please provide a help url")][string] $HelpUrl,
  9. [Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
  10. [Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
  11. [Parameter(Mandatory, HelpMessage="Please provide an alias for localhost")][string] $LoopbackAlias,
  12. [bool] $clean
  13. )
  14. [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
  15. $ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
  16. # check preconditions
  17. if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
  18. {
  19. Write-Error "Unable to find git.exe in your PATH (try: choco install git)"
  20. exit 1
  21. }
  22. if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
  23. {
  24. Write-Error "Unable to find mvn.cmd in your PATH (try: choco install maven)"
  25. exit 1
  26. }
  27. if ((Get-Command 'wix' -ErrorAction SilentlyContinue) -eq $null)
  28. {
  29. Write-Error 'Unable to find wix in your PATH (try: dotnet tool install --global wix --version 6.0.0)'
  30. exit 1
  31. }
  32. $wixExtensions = & wix.exe extension list --global | Out-String
  33. if ($wixExtensions -notmatch 'WixToolset.UI.wixext') {
  34. Write-Error 'UI wix extension missing. Please install it with: wix.exe extension add WixToolset.UI.wixext/6.0.0 --global)'
  35. exit 1
  36. }
  37. if ($wixExtensions -notmatch 'WixToolset.Util.wixext') {
  38. Write-Error 'Util wix extension missing. Please install it with: wix.exe extension add WixToolset.Util.wixext/6.0.0 --global)'
  39. exit 1
  40. }
  41. if ($wixExtensions -notmatch 'WixToolset.BootstrapperApplications.wixext') {
  42. Write-Error 'Util wix extension missing. Please install it with: wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global)'
  43. exit 1
  44. }
  45. $buildDir = Split-Path -Parent $PSCommandPath
  46. $version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
  47. $semVerNo = $version -replace '(\d+\.\d+\.\d+).*','$1'
  48. $revisionNo = $(git rev-list --count HEAD)
  49. Write-Output "`$version=$version"
  50. Write-Output "`$semVerNo=$semVerNo"
  51. Write-Output "`$revisionNo=$revisionNo"
  52. Write-Output "`$buildDir=$buildDir"
  53. Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
  54. $copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor"
  55. # compile
  56. &mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin "-Djavafx.platform=win"
  57. Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
  58. # add runtime
  59. $runtimeImagePath = '.\runtime'
  60. if ($clean -and (Test-Path -Path $runtimeImagePath)) {
  61. Remove-Item -Path $runtimeImagePath -Force -Recurse
  62. }
  63. ## download jfx jmods
  64. $javaFxVersion='23.0.2'
  65. $javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
  66. $javaFxJmodsSHA256 = 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
  67. $javaFxJmods = '.\resources\jfxJmods.zip'
  68. if( !(Test-Path -Path $javaFxJmods) ) {
  69. Write-Output "Downloading ${javaFxJmodsUrl}..."
  70. Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
  71. }
  72. $jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
  73. if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
  74. Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
  75. , actual: $jmodsChecksumActual"
  76. exit 1;
  77. }
  78. Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
  79. Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
  80. Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
  81. ## create custom runtime
  82. ### check for JEP 493
  83. $jmodPaths="$buildDir/resources/javafx-jmods";
  84. if ((& "$Env:JAVA_HOME\bin\jlink" --help | Select-String -Pattern "Linking from run-time image enabled" -SimpleMatch | Measure-Object).Count -gt 0 ) {
  85. $jmodPaths="$Env:JAVA_HOME/jmods;" + $jmodPaths;
  86. }
  87. ### create runtime
  88. & "$Env:JAVA_HOME\bin\jlink" `
  89. --verbose `
  90. --output runtime `
  91. --module-path $jmodPaths `
  92. --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,jdk.crypto.mscapi,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
  93. --strip-native-commands `
  94. --no-header-files `
  95. --no-man-pages `
  96. --strip-debug `
  97. --compress "zip-0" #do not compress and use msi compression
  98. $appPath = ".\$AppName"
  99. if ($clean -and (Test-Path -Path $appPath)) {
  100. Remove-Item -Path $appPath -Force -Recurse
  101. }
  102. # create app dir
  103. & "$Env:JAVA_HOME\bin\jpackage" `
  104. --verbose `
  105. --type app-image `
  106. --runtime-image runtime `
  107. --input ../../target/libs `
  108. --module-path ../../target/mods `
  109. --module $ModuleAndMainClass `
  110. --dest . `
  111. --name $AppName `
  112. --vendor $Vendor `
  113. --copyright $copyright `
  114. --java-options "--enable-preview" `
  115. --java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
  116. --java-options "-Xss5m" `
  117. --java-options "-Xmx256m" `
  118. --java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
  119. --app-version "$semVerNo.$revisionNo" `
  120. --java-options "-Dfile.encoding=`"utf-8`"" `
  121. --java-options "-Djava.net.useSystemProxies=true" `
  122. --java-options "-Dcryptomator.logDir=`"@{localappdata}/$AppName`"" `
  123. --java-options "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`"" `
  124. --java-options "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`"" `
  125. --java-options "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`"" `
  126. --java-options "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`"" `
  127. --java-options "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`"" `
  128. --java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
  129. --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
  130. --java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
  131. --java-options "-Dcryptomator.showTrayIcon=true" `
  132. --java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
  133. --resource-dir resources `
  134. --icon resources/$AppName.ico
  135. #Create RTF license for msi
  136. &mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
  137. "-Dlicense.thirdPartyFilename=license.rtf" `
  138. "-Dlicense.fileTemplate=$buildDir\resources\licenseTemplate.ftl" `
  139. "-Dlicense.outputDirectory=$buildDir\resources\" `
  140. "-Dlicense.includedScopes=compile" `
  141. "-Dlicense.excludedGroups=^org\.cryptomator" `
  142. "-Dlicense.failOnMissing=true" `
  143. "-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
  144. # patch app dir
  145. Copy-Item "contrib\*" -Destination "$AppName"
  146. attrib -r "$AppName\$AppName.exe"
  147. # patch batch script to set hostfile
  148. $webDAVPatcher = "$AppName\patchWebDAV.bat"
  149. try {
  150. (Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$LoopbackAlias`"" | Set-Content $webDAVPatcher
  151. } catch {
  152. Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
  153. exit 1
  154. }
  155. # create .msi
  156. $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
  157. $Env:JP_WIXHELPER_DIR = "."
  158. & "$Env:JAVA_HOME\bin\jpackage" `
  159. --verbose `
  160. --type msi `
  161. --win-upgrade-uuid $UpgradeUUID `
  162. --app-image $AppName `
  163. --dest installer `
  164. --name $AppName `
  165. --vendor $Vendor `
  166. --copyright $copyright `
  167. --app-version "$semVerNo.$revisionNo" `
  168. --win-menu `
  169. --win-dir-chooser `
  170. --win-shortcut-prompt `
  171. --win-menu-group $AppName `
  172. --resource-dir resources `
  173. --license-file resources/license.rtf `
  174. --win-update-url $UpdateUrl `
  175. --about-url $AboutUrl `
  176. --file-associations resources/FAvaultFile.properties
  177. if ($LASTEXITCODE -ne 0) {
  178. Write-Error "jpackage MSI failed with exit code $LASTEXITCODE"
  179. return 1;
  180. }
  181. #Create RTF license for bundle
  182. &mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
  183. "-Dlicense.thirdPartyFilename=license.rtf" `
  184. "-Dlicense.fileTemplate=$buildDir\bundle\resources\licenseTemplate.ftl" `
  185. "-Dlicense.outputDirectory=$buildDir\bundle\resources\" `
  186. "-Dlicense.includedScopes=compile" `
  187. "-Dlicense.excludedGroups=^org\.cryptomator" `
  188. "-Dlicense.failOnMissing=true" `
  189. "-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
  190. # download Winfsp
  191. $winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
  192. Write-Output "Downloading ${winfspMsiUrl}..."
  193. Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
  194. # download legacy-winfsp uninstaller
  195. $winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
  196. Write-Output "Downloading ${winfspUninstaller}..."
  197. Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
  198. # copy MSI to bundle resources
  199. Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi" -Force
  200. # create bundle including winfsp
  201. & wix build `
  202. -define BundleName="$AppName" `
  203. -define BundleVersion="$semVerNo.$revisionNo" `
  204. -define BundleVendor="$Vendor" `
  205. -define BundleCopyright="$copyright" `
  206. -define AboutUrl="$AboutUrl" `
  207. -define HelpUrl="$HelpUrl" `
  208. -define UpdateUrl="$UpdateUrl" `
  209. -ext "WixToolset.Util.wixext" `
  210. -ext "WixToolset.BootstrapperApplications.wixext" `
  211. .\bundle\bundleWithWinfsp.wxs `
  212. -out "installer\$AppName-Installer.exe"