win-exe.yml 14 KB

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