win-exe.yml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. name: Build Windows Installer
  2. on:
  3. release:
  4. types: [published]
  5. workflow_dispatch:
  6. inputs:
  7. version:
  8. description: 'Version'
  9. required: false
  10. env:
  11. JAVA_VERSION: 19
  12. JAVA_DIST: 'zulu'
  13. JAVA_CACHE: 'maven'
  14. defaults:
  15. run:
  16. shell: bash
  17. jobs:
  18. get-version:
  19. uses: ./.github/workflows/get-version.yml
  20. with:
  21. version: ${{ github.event.inputs.version }}
  22. build-msi:
  23. name: Build .msi Installer
  24. runs-on: windows-latest
  25. needs: [get-version]
  26. env:
  27. LOOPBACK_ALIAS: 'cryptomator-vault'
  28. steps:
  29. - uses: actions/checkout@v3
  30. - name: Setup Java
  31. uses: actions/setup-java@v3
  32. with:
  33. distribution: ${{ env.JAVA_DIST }}
  34. java-version: ${{ env.JAVA_VERSION }}
  35. cache: ${{ env.JAVA_CACHE }}
  36. - name: Set version
  37. run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
  38. - name: Run maven
  39. run: mvn -B clean package -Pdependency-check,win -DskipTests
  40. - name: Patch target dir
  41. run: |
  42. cp LICENSE.txt target
  43. cp dist/linux/launcher.sh target
  44. cp target/cryptomator-*.jar target/mods
  45. - name: Run jlink
  46. run: >
  47. ${JAVA_HOME}/bin/jlink
  48. --verbose
  49. --output runtime
  50. --module-path "${JAVA_HOME}/jmods"
  51. --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
  52. --strip-native-commands
  53. --no-header-files
  54. --no-man-pages
  55. --strip-debug
  56. --compress=1
  57. - name: Run jpackage
  58. run: >
  59. ${JAVA_HOME}/bin/jpackage
  60. --verbose
  61. --type app-image
  62. --runtime-image runtime
  63. --input target/libs
  64. --module-path target/mods
  65. --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
  66. --dest appdir
  67. --name Cryptomator
  68. --vendor "Skymatic GmbH"
  69. --copyright "(C) 2016 - 2022 Skymatic GmbH"
  70. --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
  71. --java-options "-Xss5m"
  72. --java-options "-Xmx256m"
  73. --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
  74. --java-options "-Dfile.encoding=\"utf-8\""
  75. --java-options "-Dcryptomator.logDir=\"~/AppData/Roaming/Cryptomator\""
  76. --java-options "-Dcryptomator.pluginDir=\"~/AppData/Roaming/Cryptomator/Plugins\""
  77. --java-options "-Dcryptomator.settingsPath=\"~/AppData/Roaming/Cryptomator/settings.json\""
  78. --java-options "-Dcryptomator.p12Path=\"~/AppData/Roaming/Cryptomator/key.p12\""
  79. --java-options "-Dcryptomator.ipcSocketPath=\"~/AppData/Roaming/Cryptomator/ipc.socket\""
  80. --java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\""
  81. --java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\""
  82. --java-options "-Dcryptomator.showTrayIcon=true"
  83. --java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
  84. --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
  85. --java-options "-Dcryptomator.integrationsWin.keychainPaths=\"~/AppData/Roaming/Cryptomator/keychain.json\""
  86. --resource-dir dist/win/resources
  87. --icon dist/win/resources/Cryptomator.ico
  88. - name: Patch Application Directory
  89. run: |
  90. cp dist/win/contrib/* appdir/Cryptomator
  91. - name: Set LOOPBACK_ALIAS in patchWebDAV.bat
  92. shell: pwsh
  93. run: |
  94. $patchScript = "appdir\Cryptomator\patchWebDAV.bat"
  95. try {
  96. (Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ env.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript
  97. } catch {
  98. Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
  99. exit 1
  100. }
  101. - name: Fix permissions
  102. run: attrib -r appdir/Cryptomator/Cryptomator.exe
  103. shell: pwsh
  104. - name: Codesign
  105. uses: skymatic/code-sign-action@v1
  106. with:
  107. certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
  108. password: ${{ secrets.WIN_CODESIGN_P12_PW }}
  109. certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
  110. description: Cryptomator
  111. timestampUrl: 'http://timestamp.digicert.com'
  112. folder: appdir/Cryptomator
  113. recursive: true
  114. - name: Generate license for MSI
  115. run: >
  116. mvn -B license:add-third-party
  117. "-Dlicense.thirdPartyFilename=license.rtf"
  118. "-Dlicense.outputDirectory=dist/win/resources"
  119. "-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl"
  120. "-Dlicense.includedScopes=compile"
  121. "-Dlicense.excludedGroups=^org\.cryptomator"
  122. "-Dlicense.failOnMissing=true"
  123. "-Dlicense.licenseMergesUrl=file:///${{ github.workspace }}/license/merges"
  124. shell: pwsh
  125. - name: Create MSI
  126. run: >
  127. ${JAVA_HOME}/bin/jpackage
  128. --verbose
  129. --type msi
  130. --win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775
  131. --app-image appdir/Cryptomator
  132. --dest installer
  133. --name Cryptomator
  134. --vendor "Skymatic GmbH"
  135. --copyright "(C) 2016 - 2022 Skymatic GmbH"
  136. --app-version "${{ needs.get-version.outputs.semVerNum }}"
  137. --win-menu
  138. --win-dir-chooser
  139. --win-shortcut-prompt
  140. --win-update-url "https:\\cryptomator.org"
  141. --win-menu-group Cryptomator
  142. --resource-dir dist/win/resources
  143. --license-file dist/win/resources/license.rtf
  144. --file-associations dist/win/resources/FAvaultFile.properties
  145. env:
  146. JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
  147. - name: Codesign MSI
  148. uses: skymatic/code-sign-action@v1
  149. with:
  150. certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
  151. password: ${{ secrets.WIN_CODESIGN_P12_PW }}
  152. certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
  153. description: Cryptomator Installer
  154. timestampUrl: 'http://timestamp.digicert.com'
  155. folder: installer
  156. - name: Add possible alpha/beta tags to installer name
  157. run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi
  158. - name: Create detached GPG signature with key 615D449FE6E6A235
  159. run: |
  160. echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
  161. echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a Cryptomator-*.msi
  162. env:
  163. GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
  164. GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
  165. - name: Upload artifacts
  166. uses: actions/upload-artifact@v3
  167. with:
  168. name: msi
  169. path: |
  170. Cryptomator-*.msi
  171. Cryptomator-*.asc
  172. if-no-files-found: error
  173. - name: Publish .msi on GitHub Releases
  174. if: startsWith(github.ref, 'refs/tags/')
  175. uses: softprops/action-gh-release@v1
  176. with:
  177. fail_on_unmatched_files: true
  178. token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
  179. files: |
  180. *.msi
  181. *.asc
  182. call-winget-flow:
  183. needs: [get-version, build-msi]
  184. if: github.event.action == 'published' && needs.get-version.outputs.type == 'stable'
  185. uses: ./.github/workflows/winget.yml
  186. with:
  187. releaseTag: ${{ github.event.release.tag_name }}
  188. secrets: inherit
  189. build-exe:
  190. name: Build .exe installer
  191. runs-on: windows-latest
  192. needs: [version, build-msi]
  193. steps:
  194. - uses: actions/checkout@v3
  195. - name: Download .msi
  196. uses: actions/download-artifact@v3
  197. with:
  198. name: msi
  199. path: dist/win/bundle/resources
  200. - name: Strip version info from msi file name
  201. run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
  202. - uses: actions/setup-java@v3
  203. with:
  204. distribution: ${{ env.JAVA_DIST }}
  205. java-version: ${{ env.JAVA_VERSION }}
  206. cache: ${{ env.JAVA_CACHE }}
  207. - name: Generate license for exe
  208. run: >
  209. mvn -B license:add-third-party
  210. "-Dlicense.thirdPartyFilename=license.rtf"
  211. "-Dlicense.fileTemplate=dist/win/bundle/resources/licenseTemplate.ftl"
  212. "-Dlicense.outputDirectory=dist/win/bundle/resources"
  213. "-Dlicense.includedScopes=compile"
  214. "-Dlicense.excludedGroups=^org\.cryptomator"
  215. "-Dlicense.failOnMissing=true"
  216. "-Dlicense.licenseMergesUrl=file:///${{ github.workspace }}/license/merges"
  217. shell: pwsh
  218. - name: Download WinFsp
  219. run: |
  220. $winfspUrl= (Select-String -Path ".\dist\win\bundle\resources\winfsp-download.url" -Pattern 'https:.*').Matches.Value
  221. curl --output dist/win/bundle/resources/winfsp.msi -L $winfspUrl
  222. shell: pwsh
  223. - name: Compile to wixObj file
  224. run: >
  225. "${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
  226. -ext WixBalExtension
  227. -out dist/win/bundle/
  228. -dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
  229. -dBundleVendor="Skymatic GmbH"
  230. -dBundleCopyright="(C) 2016 - 2022 Skymatic GmbH"
  231. -dAboutUrl="https://cryptomator.org"
  232. -dHelpUrl="https://cryptomator.org/contact"
  233. -dUpdateUrl="https://cryptomator.org/downloads/"
  234. - name: Create executable with linker
  235. run: >
  236. "${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
  237. -ext WixBalExtension
  238. -out installer/unsigned/Cryptomator-Installer.exe
  239. - name: Detach burn engine in preparation to sign
  240. run: >
  241. "${WIX}/bin/insignia.exe"
  242. -ib installer/unsigned/Cryptomator-Installer.exe
  243. -o tmp/engine.exe
  244. - name: Codesign burn engine
  245. uses: skymatic/code-sign-action@v1
  246. with:
  247. certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
  248. password: ${{ secrets.WIN_CODESIGN_P12_PW }}
  249. certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
  250. description: Cryptomator Installer
  251. timestampUrl: 'http://timestamp.digicert.com'
  252. folder: tmp
  253. - name: Reattach signed burn engine to installer
  254. run : >
  255. "${WIX}/bin/insignia.exe"
  256. -ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe
  257. -o installer/Cryptomator-Installer.exe
  258. - name: Codesign EXE
  259. uses: skymatic/code-sign-action@v1
  260. with:
  261. certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
  262. password: ${{ secrets.WIN_CODESIGN_P12_PW }}
  263. certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
  264. description: Cryptomator Installer
  265. timestampUrl: 'http://timestamp.digicert.com'
  266. folder: installer
  267. - name: Add possible alpha/beta tags to installer name
  268. run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.exe
  269. - name: Create detached GPG signature with key 615D449FE6E6A235
  270. run: |
  271. echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
  272. echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a Cryptomator-*.exe
  273. env:
  274. GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
  275. GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
  276. - name: Upload artifacts
  277. uses: actions/upload-artifact@v3
  278. with:
  279. name: exe
  280. path: |
  281. Cryptomator-*.exe
  282. Cryptomator-*.asc
  283. if-no-files-found: error
  284. - name: Publish .msi on GitHub Releases
  285. if: startsWith(github.ref, 'refs/tags/')
  286. uses: softprops/action-gh-release@v1
  287. with:
  288. fail_on_unmatched_files: true
  289. token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
  290. files: |
  291. Cryptomator-*.exe
  292. Cryptomator-*.asc
  293. allowlist:
  294. name: Anti Virus Allowlisting
  295. if: startsWith(github.ref, 'refs/tags/')
  296. runs-on: ubuntu-latest
  297. needs: [build-msi, build-exe]
  298. steps:
  299. - name: Download .msi
  300. uses: actions/download-artifact@v2
  301. with:
  302. name: msi
  303. path: msi
  304. - name: Download .exe
  305. uses: actions/download-artifact@v2
  306. with:
  307. name: exe
  308. path: exe
  309. - name: Collect files
  310. run: |
  311. mkdir files
  312. cp msi/*.msi files
  313. cp exe/*.exe files
  314. - name: Upload to Kaspersky
  315. uses: SamKirkland/FTP-Deploy-Action@4.3.0
  316. with:
  317. protocol: ftps
  318. server: allowlist.kaspersky-labs.com
  319. port: 990
  320. username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
  321. password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
  322. local-dir: files/
  323. - name: Upload to Avast
  324. uses: SamKirkland/FTP-Deploy-Action@4.3.0
  325. with:
  326. protocol: ftp
  327. server: whitelisting.avast.com
  328. port: 21
  329. username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
  330. password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
  331. local-dir: files/