win-exe.yml 14 KB

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