Browse Source

Merge pull request #2103 from cryptomator/feature/separate-release-actions

Build binary packages in separate workflows
Sebastian Stenzel 3 năm trước cách đây
mục cha
commit
a1becd9a1f

+ 151 - 0
.github/workflows/appimage.yml

@@ -0,0 +1,151 @@
+name: Build AppImage
+
+on:
+  release:
+    types: [published]
+  workflow_dispatch:
+
+env:
+  JAVA_VERSION: 17
+
+jobs:
+  build:
+    name: Build AppImage
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Setup Java
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'temurin'
+          java-version: ${{ env.JAVA_VERSION }}
+          cache: 'maven'
+      - id: versions 
+        name: Apply version information
+        run: |
+          if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then
+            SEM_VER_STR=${GITHUB_REF##*/}
+            mvn versions:set -DnewVersion=${SEM_VER_STR}
+          else
+            SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
+          fi
+          SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
+          REVCOUNT=`git rev-list --count HEAD`
+          echo "::set-output name=semVerStr::${SEM_VER_STR}"
+          echo "::set-output name=semVerNum::${SEM_VER_NUM}"
+          echo "::set-output name=revNum::${REVCOUNT}"
+      - name: Validate Version
+        uses: skymatic/semver-validation-action@v1
+        with:
+          version: ${{ steps.versions.outputs.semVerStr }}
+      - name: Run maven
+        run: mvn -B clean package -Pdependency-check,linux -DskipTests
+      - name: Patch target dir
+        run: |
+          cp LICENSE.txt target
+          cp dist/linux/launcher.sh target
+          cp target/cryptomator-*.jar target/mods
+      - name: Run jlink
+        run: >
+          ${JAVA_HOME}/bin/jlink
+          --verbose
+          --output runtime
+          --module-path "${JAVA_HOME}/jmods"
+          --add-modules java.base,java.desktop,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
+          --no-header-files
+          --no-man-pages
+          --strip-debug
+          --compress=1
+      - name: Run jpackage
+        run: >
+          ${JAVA_HOME}/bin/jpackage
+          --verbose
+          --type app-image
+          --runtime-image runtime
+          --input target/libs
+          --module-path target/mods
+          --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+          --dest appdir
+          --name Cryptomator
+          --vendor "Skymatic GmbH"
+          --copyright "(C) 2016 - 2022 Skymatic GmbH"
+          --app-version "${{  steps.versions.outputs.semVerNum }}.${{  steps.versions.outputs.revNum }}"
+          --java-options "-Xss5m"
+          --java-options "-Xmx256m"
+          --java-options "-Dcryptomator.appVersion=\"${{  steps.versions.outputs.semVerStr }}\""
+          --java-options "-Dfile.encoding=\"utf-8\""
+          --java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\""
+          --java-options "-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\""
+          --java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\""
+          --java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\""
+          --java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\""
+          --java-options "-Dcryptomator.showTrayIcon=false"
+          --java-options "-Dcryptomator.buildNumber=\"appimage-${{  steps.versions.outputs.revNum }}\""
+          --resource-dir dist/linux/resources
+      - name: Patch Cryptomator.AppDir
+        run: |
+          mv appdir/Cryptomator Cryptomator.AppDir
+          cp -r dist/linux/appimage/resources/AppDir/* Cryptomator.AppDir/
+          envsubst '${REVISION_NO} ${SEMVER_STR}' < dist/linux/appimage/resources/AppDir/bin/cryptomator.sh > Cryptomator.AppDir/bin/cryptomator.sh
+          cp dist/linux/common/org.cryptomator.Cryptomator256.png Cryptomator.AppDir/usr/share/icons/hicolor/256x256/apps/org.cryptomator.Cryptomator.png
+          cp dist/linux/common/org.cryptomator.Cryptomator512.png Cryptomator.AppDir/usr/share/icons/hicolor/512x512/apps/org.cryptomator.Cryptomator.png
+          cp dist/linux/common/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg
+          cp dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.metainfo.xml
+          cp dist/linux/common/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/usr/share/applications/org.cryptomator.Cryptomator.desktop
+          cp dist/linux/common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
+          ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
+          ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
+          ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
+          ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
+          ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
+        env:
+          REVISION_NO: ${{  steps.versions.outputs.revNum }}
+          SEMVER_STR: ${{  steps.versions.outputs.semVerStr }}
+      - name: Extract libjffi.so # workaround for https://github.com/cryptomator/cryptomator-linux/issues/27
+        run: |
+          JFFI_NATIVE_JAR=`ls lib/app/ | grep -e 'jffi-[1-9]\.[0-9]\{1,2\}.[0-9]\{1,2\}-native.jar'`
+          ${JAVA_HOME}/bin/jar -xf lib/app/${JFFI_NATIVE_JAR} /jni/x86_64-Linux/
+          mv jni/x86_64-Linux/* lib/app/libjffi.so
+        working-directory: Cryptomator.AppDir
+      - name: Download AppImageKit
+        run: |
+          curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o appimagetool.AppImage
+          chmod +x appimagetool.AppImage
+          ./appimagetool.AppImage --appimage-extract
+      - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
+        run: |
+          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
+          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign README.md
+        env:
+          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
+          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
+      - name: Build AppImage
+        run: >
+          ./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{  steps.versions.outputs.semVerStr }}-x86_64.AppImage
+          -u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync'
+          --sign --sign-key=615D449FE6E6A235 --sign-args="--batch --pinentry-mode loopback"
+      - name: Create detached GPG signatures
+        run: |
+          gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage
+          gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage.zsync
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: appimage
+          path: |
+            cryptomator-*.AppImage
+            cryptomator-*.AppImage.zsync
+            cryptomator-*.asc
+          if-no-files-found: error
+      - name: Publish AppImage on GitHub Releases
+        if: startsWith(github.ref, 'refs/tags/')
+        uses: softprops/action-gh-release@v1
+        with:
+          fail_on_unmatched_files: true
+          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+          files: |
+            *.AppImage
+            *.zsync
+            *.asc

+ 13 - 1
.github/workflows/build.yml

@@ -48,4 +48,16 @@ jobs:
         run: bash <(curl -Ls https://coverage.codacy.com/get.sh)
         env:
           CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
-        continue-on-error: true
+        continue-on-error: true
+      - name: Draft a release
+        if: startsWith(github.ref, 'refs/tags/')
+        uses: softprops/action-gh-release@v1
+        with:
+          draft: true
+          discussion_category_name: releases
+          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+          generate_release_notes: true
+          body: |-
+            :construction: Work in Progress
+            
+            ---

+ 118 - 0
.github/workflows/debian.yml

@@ -0,0 +1,118 @@
+name: Build Debian Package
+
+on:
+  release:
+    types: [published]
+  workflow_dispatch:
+    inputs:
+      dput:
+        description: 'Upload to PPA'
+        required: true
+        default: false
+        type: boolean
+
+env:
+  JAVA_VERSION: 17
+
+jobs:
+  build:
+    name: Build Debian Package
+    runs-on: ubuntu-18.04
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Install build tools
+        run: |
+          sudo apt-get update
+          sudo apt-get install debhelper devscripts dput
+      - name: Setup Java
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'temurin'
+          java-version: ${{ env.JAVA_VERSION }}
+          cache: 'maven'
+      - id: versions 
+        name: Apply version information
+        run: |
+          if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then
+            SEM_VER_STR=${GITHUB_REF##*/}
+            mvn versions:set -DnewVersion=${SEM_VER_STR}
+          else
+            SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
+          fi
+          SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
+          REVCOUNT=`git rev-list --count HEAD`
+          echo "::set-output name=semVerStr::${SEM_VER_STR}"
+          echo "::set-output name=semVerNum::${SEM_VER_NUM}"
+          echo "::set-output name=revNum::${REVCOUNT}"
+          echo "::set-output name=ppaVerStr::${SEM_VER_STR/-/\~}-${REVCOUNT}"
+      - name: Validate Version
+        uses: skymatic/semver-validation-action@v1
+        with:
+          version: ${{ steps.versions.outputs.semVerStr }}
+      - name: Run maven
+        run: mvn -B clean package -Pdependency-check,linux -DskipTests
+      - name: Create orig.tar.gz with common/ libs/ mods/
+        run: |
+          mkdir pkgdir
+          cp -r target/libs pkgdir
+          cp -r target/mods pkgdir
+          cp -r dist/linux/common/ pkgdir
+          cp target/cryptomator-*.jar pkgdir/mods
+          tar -cJf cryptomator_${{ steps.versions.outputs.ppaVerStr }}.orig.tar.xz -C pkgdir .
+      - name: Patch and rename pkgdir
+        run: |
+          cp -r dist/linux/debian/ pkgdir
+          export RFC2822_TIMESTAMP=`date --rfc-2822`
+          envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules
+          envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
+          find . -name "*.jar" >> pkgdir/debian/source/include-binaries
+          mv pkgdir cryptomator_${{ steps.versions.outputs.ppaVerStr }}
+        env:
+          SEMVER_STR: ${{ steps.versions.outputs.semVerStr }}
+          VERSION_NUM: ${{ steps.versions.outputs.semVerNum }}
+          REVISION_NUM: ${{ steps.versions.outputs.revNum }}
+          PPA_VERSION: ${{ steps.versions.outputs.ppaVerStr }}-0ppa1
+      - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
+        run: |
+          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
+          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign README.md
+        env:
+          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
+          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
+      - name: debuild
+        run: |
+          debuild -S -sa -d
+          debuild -b -sa -d
+        env:
+          DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
+          DEBSIGN_KEYID: 615D449FE6E6A235
+        working-directory: cryptomator_${{ steps.versions.outputs.ppaVerStr }}
+      - name: Create detached GPG signatures
+        run: |
+          gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: linux-deb-package
+          path: |
+            cryptomator_*.dsc
+            cryptomator_*.orig.tar.xz
+            cryptomator_*.debian.tar.xz
+            cryptomator_*_source.buildinfo
+            cryptomator_*_source.changes
+            cryptomator_*_amd64.deb
+            cryptomator_*.asc
+      - name: Publish on PPA
+        if: startsWith(github.ref, 'refs/tags/') || github.event.inputs.dput == 'true'
+        run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
+      - name: Publish Debian package on GitHub Releases
+        if: startsWith(github.ref, 'refs/tags/')
+        uses: softprops/action-gh-release@v1
+        with:
+          fail_on_unmatched_files: true
+          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+          files: |
+            cryptomator_*_amd64.deb
+            cryptomator_*.asc

+ 232 - 0
.github/workflows/mac-dmg.yml

@@ -0,0 +1,232 @@
+name: Build macOS .dmg
+
+on:
+  release:
+    types: [published]
+  workflow_dispatch:
+
+env:
+  JAVA_VERSION: 17
+
+jobs:
+  build:
+    name: Build Cryptomator.app
+    runs-on: macos-11
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Setup Java
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'temurin'
+          java-version: ${{ env.JAVA_VERSION }}
+          cache: 'maven'
+      - id: versions 
+        name: Apply version information
+        run: |
+          if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then
+            SEM_VER_STR=${GITHUB_REF##*/}
+            mvn versions:set -DnewVersion=${SEM_VER_STR}
+          else
+            SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
+          fi
+          SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
+          REVCOUNT=`git rev-list --count HEAD`
+          echo "::set-output name=semVerStr::${SEM_VER_STR}"
+          echo "::set-output name=semVerNum::${SEM_VER_NUM}"
+          echo "::set-output name=revNum::${REVCOUNT}"
+      - name: Validate Version
+        uses: skymatic/semver-validation-action@v1
+        with:
+          version: ${{ steps.versions.outputs.semVerStr }}
+      - name: Run maven
+        run: mvn -B clean package -Pdependency-check,mac -DskipTests
+      - name: Patch target dir
+        run: |
+          cp LICENSE.txt target
+          cp dist/mac/launcher.sh target
+          cp target/cryptomator-*.jar target/mods
+      - name: Run jlink
+        run: >
+          ${JAVA_HOME}/bin/jlink
+          --verbose
+          --output runtime
+          --module-path "${JAVA_HOME}/jmods"
+          --add-modules java.base,java.desktop,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
+          --strip-native-commands
+          --no-header-files
+          --no-man-pages
+          --strip-debug
+          --compress=1
+      - name: Run jpackage
+        run: >
+          ${JAVA_HOME}/bin/jpackage
+          --verbose
+          --type app-image
+          --runtime-image runtime
+          --input target/libs
+          --module-path target/mods
+          --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+          --dest appdir
+          --name Cryptomator
+          --vendor "Skymatic GmbH"
+          --copyright "(C) 2016 - 2022 Skymatic GmbH"
+          --app-version "${{ steps.versions.outputs.semVerNum }}"
+          --java-options "-Xss5m"
+          --java-options "-Xmx256m"
+          --java-options "-Dcryptomator.appVersion=\"${{ steps.versions.outputs.semVerStr }}\""
+          --java-options "-Dfile.encoding=\"utf-8\""
+          --java-options "-Dapple.awt.enableTemplateImages=true"
+          --java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\""
+          --java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\""
+          --java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\""
+          --java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\""
+          --java-options "-Dcryptomator.showTrayIcon=true"
+          --java-options "-Dcryptomator.buildNumber=\"dmg-${{ steps.versions.outputs.revNum }}\""
+          --mac-package-identifier org.cryptomator
+          --resource-dir dist/mac/resources
+      - name: Patch Cryptomator.app
+        run: |
+          mv appdir/Cryptomator.app Cryptomator.app
+          mv dist/mac/resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/
+          sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
+          sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
+        env:
+          VERSION_NO: ${{ steps.versions.outputs.semVerNum }}
+          REVISION_NO: ${{ steps.versions.outputs.revNum }}
+      - name: Install codesign certificate
+        run: |
+          # create variables
+          CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
+          KEYCHAIN_PATH=$RUNNER_TEMP/codesign.keychain-db
+
+          # import certificate and provisioning profile from secrets
+          echo -n "$CODESIGN_P12_BASE64" | base64 --decode --output $CERTIFICATE_PATH
+
+          # create temporary keychain
+          security create-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
+          security set-keychain-settings -lut 900 $KEYCHAIN_PATH
+          security unlock-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
+
+          # import certificate to keychain
+          security import $CERTIFICATE_PATH -P "$CODESIGN_P12_PW" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
+          security list-keychain -d user -s $KEYCHAIN_PATH
+        env:
+          CODESIGN_P12_BASE64: ${{ secrets.MACOS_CODESIGN_P12_BASE64 }}
+          CODESIGN_P12_PW: ${{ secrets.MACOS_CODESIGN_P12_PW }}
+          CODESIGN_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }}
+      - name: Codesign
+        run: |
+          find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
+          for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
+            if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
+              JAR_FILENAME=$(basename ${JAR_PATH})
+              OUTPUT_PATH=${JAR_PATH%.*}
+              echo "Codesigning libs in ${JAR_FILENAME}..."
+              unzip -q ${JAR_PATH} -d ${OUTPUT_PATH}
+              find ${OUTPUT_PATH} -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
+              find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
+              rm ${JAR_PATH}
+              pushd ${OUTPUT_PATH} > /dev/null
+              zip -qr ../${JAR_FILENAME} *
+              popd > /dev/null
+              rm -r ${OUTPUT_PATH}
+            fi
+          done
+          echo "Codesigning Cryptomator.app..."
+          codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
+        env:
+          CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
+      - name: Prepare .dmg contents
+        run: |
+          mkdir dmg
+          mv Cryptomator.app dmg
+          cp dist/mac/dmg/resources/macFUSE.webloc dmg
+          ls -l dmg
+      - name: Install create-dmg
+        run: |
+          brew install create-dmg
+          create-dmg --help
+      - name: Create .dmg
+        run: >
+          create-dmg
+          --volname Cryptomator
+          --volicon "dist/mac/dmg/resources/Cryptomator-Volume.icns"
+          --background "dist/mac/dmg/resources/Cryptomator-background.tiff"
+          --window-pos 400 100
+          --window-size 640 694
+          --icon-size 128
+          --icon "Cryptomator.app" 128 245
+          --hide-extension "Cryptomator.app"
+          --icon "macFUSE.webloc" 320 501
+          --hide-extension "macFUSE.webloc"
+          --app-drop-link 512 245
+          --eula "dist/mac/dmg/resources/license.rtf"
+          --icon ".background" 128 758
+          --icon ".fseventsd" 320 758
+          --icon ".VolumeIcon.icns" 512 758
+          Cryptomator-${VERSION_NO}.dmg dmg
+        env:
+          VERSION_NO: ${{ steps.versions.outputs.semVerNum }}
+      - name: Install notarization credentials
+        if: startsWith(github.ref, 'refs/tags/')
+        run: |
+          # create temporary keychain
+          KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
+          security create-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
+          security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
+          security unlock-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
+
+          # import credentials from secrets
+          sudo xcode-select -s /Applications/Xcode_13.0.app
+          xcrun notarytool store-credentials "${NOTARIZATION_KEYCHAIN_PROFILE}" --apple-id "${NOTARIZATION_APPLE_ID}" --password "${NOTARIZATION_PW}" --team-id "${NOTARIZATION_TEAM_ID}" --keychain "${KEYCHAIN_PATH}"
+        env:
+          NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
+          NOTARIZATION_APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
+          NOTARIZATION_PW: ${{ secrets.MACOS_NOTARIZATION_PW }}
+          NOTARIZATION_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
+          NOTARIZATION_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_NOTARIZATION_TMP_KEYCHAIN_PW }}
+      - name: Notarize .dmg
+        if: startsWith(github.ref, 'refs/tags/')
+        run: |
+          KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
+          sudo xcode-select -s /Applications/Xcode_13.0.app
+          xcrun notarytool submit Cryptomator-*.dmg --keychain-profile "${NOTARIZATION_KEYCHAIN_PROFILE}" --keychain "${KEYCHAIN_PATH}" --wait
+          xcrun stapler staple Cryptomator-*.dmg
+        env:
+          NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
+      - name: Add possible alpha/beta tags to installer name
+        run: mv Cryptomator-*.dmg Cryptomator-${{ steps.versions.outputs.semVerStr }}.dmg
+      - name: Create detached GPG signature with key 615D449FE6E6A235
+        run: |
+          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
+          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a Cryptomator-*.dmg
+        env:
+          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
+          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
+      - name: Clean up codesign certificate
+        if: ${{ always() }}
+        run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
+        continue-on-error: true
+      - name: Clean up notarization credentials
+        if: ${{ always() }}
+        run: security delete-keychain $RUNNER_TEMP/notarization.keychain-db
+        continue-on-error: true
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: dmg
+          path: Cryptomator-*.dmg
+          if-no-files-found: error
+      - name: Publish dmg on GitHub Releases
+        if: startsWith(github.ref, 'refs/tags/')
+        uses: softprops/action-gh-release@v1
+        with:
+          fail_on_unmatched_files: true
+          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+          files: |
+            *.dmg
+            *.asc
+
+

+ 0 - 738
.github/workflows/release.yml

@@ -1,738 +0,0 @@
-name: Installers and Release
-
-on:
-  workflow_dispatch:
-    inputs:
-      semver:
-        description: 'SemVer'
-        required: true
-        default: '0.99.99-SNAPSHOT'
-  push:
-    tags: # see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
-    - '[0-9]+.[0-9]+.[0-9]+'
-    - '[0-9]+.[0-9]+.[0-9]+-*'
-
-env:
-  JAVA_VERSION: 17
-
-defaults:
-  run:
-    shell: bash
-
-jobs:
-
-#
-# Buildkit
-#
-  buildkit:
-    name: Build ${{ matrix.profile }}-buildkit
-    runs-on: ${{ matrix.os }}
-    strategy:
-      fail-fast: true
-      matrix:
-        include:
-        - os: ubuntu-latest
-          profile: linux
-        - os: windows-latest
-          profile: win
-        - os: macos-latest
-          profile: mac
-    steps:
-      - uses: actions/checkout@v2
-      - uses: actions/setup-java@v2
-        with:
-          distribution: 'temurin'
-          java-version: ${{ env.JAVA_VERSION }}
-          cache: 'maven'
-      - name: Ensure to use tagged version
-        run: mvn versions:set -DnewVersion=${GITHUB_REF##*/} # use shell parameter expansion to strip of 'refs/tags'
-        if: startsWith(github.ref, 'refs/tags/')
-      - name: Build and Test
-        run: mvn -B clean package -Pdependency-check,${{ matrix.profile }}
-      - name: Patch buildkit
-        run: |
-          cp LICENSE.txt target
-          cp dist/${{ matrix.profile }}/launcher* target
-          cp target/cryptomator-*.jar target/mods
-      - name: Upload ${{ matrix.profile }}-buildkit
-        uses: actions/upload-artifact@v2
-        with:
-          name: ${{ matrix.profile }}-buildkit
-          path: |
-            target/libs
-            target/mods
-            target/LICENSE.txt
-            target/launcher*
-          if-no-files-found: error
-
-#
-# Release Metadata
-#
-  metadata:
-    name: Determine Version Metadata
-    runs-on: ubuntu-latest
-    outputs:
-      semVerNum: ${{ steps.versions.outputs.semVerNum }}
-      semVerStr: ${{ steps.versions.outputs.semVerStr }}
-      ppaVerStr: ${{ steps.versions.outputs.ppaVerStr }}
-      revNum: ${{ steps.versions.outputs.revNum }}
-    steps:
-      - uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
-      - id: versions
-        run: |
-          if [[ $GITHUB_REF == refs/tags/* ]]; then
-            SEM_VER_STR=${GITHUB_REF##*/}
-          else
-            SEM_VER_STR=${{ github.event.inputs.semver }}
-          fi
-          SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
-          REVCOUNT=`git rev-list --count HEAD`
-          echo "::set-output name=semVerStr::${SEM_VER_STR}"
-          echo "::set-output name=semVerNum::${SEM_VER_NUM}"
-          echo "::set-output name=ppaVerStr::${SEM_VER_STR/-/\~}-${REVCOUNT}"
-          echo "::set-output name=revNum::${REVCOUNT}"
-      - uses: skymatic/semver-validation-action@v1
-        with:
-          version: ${{ steps.versions.outputs.semVerStr }}
-
-#
-# Application Directory
-#
-  appdir:
-    name: Create ${{ matrix.profile }}-appdir
-    needs: [buildkit, metadata]
-    runs-on: ${{ matrix.os }}
-    strategy:
-      fail-fast: true
-      matrix:
-        include:
-        - os: ubuntu-latest
-          profile: linux
-          jpackageoptions: >
-            --app-version "${{ needs.metadata.outputs.semVerNum }}.${{ needs.metadata.outputs.revNum }}"
-            --java-options "-Dfile.encoding=\"utf-8\""
-            --java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\""
-            --java-options "-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\""
-            --java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\""
-            --java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\""
-            --java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\""
-            --java-options "-Dcryptomator.showTrayIcon=false"
-            --java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.metadata.outputs.revNum }}\""
-            --resource-dir dist/linux/resources
-        - os: windows-latest
-          profile: win
-          jpackageoptions: >
-            --app-version "${{ needs.metadata.outputs.semVerNum }}.${{ needs.metadata.outputs.revNum }}"
-            --java-options "-Dfile.encoding=\"utf-8\""
-            --java-options "-Dcryptomator.logDir=\"~/AppData/Roaming/Cryptomator\""
-            --java-options "-Dcryptomator.pluginDir=\"~/AppData/Roaming/Cryptomator/Plugins\""
-            --java-options "-Dcryptomator.settingsPath=\"~/AppData/Roaming/Cryptomator/settings.json\""
-            --java-options "-Dcryptomator.ipcSocketPath=\"~/AppData/Roaming/Cryptomator/ipc.socket\""
-            --java-options "-Dcryptomator.keychainPath=\"~/AppData/Roaming/Cryptomator/keychain.json\""
-            --java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\""
-            --java-options "-Dcryptomator.showTrayIcon=true"
-            --java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.metadata.outputs.revNum }}\""
-            --resource-dir dist/win/resources
-            --icon dist/win/resources/Cryptomator.ico
-        - os: macos-latest
-          profile: mac
-          jpackageoptions: >
-            --app-version "${{ needs.metadata.outputs.semVerNum }}"
-            --java-options "-Dfile.encoding=\"utf-8\""
-            --java-options "-Dapple.awt.enableTemplateImages=true"
-            --java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\""
-            --java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\""
-            --java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\""
-            --java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\""
-            --java-options "-Dcryptomator.showTrayIcon=true"
-            --java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.metadata.outputs.revNum }}\""
-            --mac-package-identifier org.cryptomator
-            --resource-dir dist/mac/resources
-    steps:
-      - uses: actions/checkout@v2
-      - uses: actions/setup-java@v2
-        with:
-          distribution: 'temurin'
-          java-version: ${{ env.JAVA_VERSION }}
-      - name: Download ${{ matrix.profile }}-buildkit
-        uses: actions/download-artifact@v2
-        with:
-          name: ${{ matrix.profile }}-buildkit
-          path: buildkit
-      - name: Create Runtime Image
-        run: >
-          ${JAVA_HOME}/bin/jlink
-          --verbose
-          --output runtime
-          --module-path "${JAVA_HOME}/jmods"
-          --add-modules java.base,java.desktop,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
-          --no-header-files
-          --no-man-pages
-          --strip-debug
-          --compress=1
-      - name: Create App Directory
-        run: >
-          ${JAVA_HOME}/bin/jpackage
-          --verbose
-          --type app-image
-          --runtime-image runtime
-          --input buildkit/libs
-          --module-path buildkit/mods
-          --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
-          --dest appdir
-          --name Cryptomator
-          --vendor "Skymatic GmbH"
-          --copyright "(C) 2016 - 2022 Skymatic GmbH"
-          --java-options "-Xss5m"
-          --java-options "-Xmx256m"
-          --java-options "-Dcryptomator.appVersion=\"${{ needs.metadata.outputs.semVerStr }}\""
-          ${{ matrix.jpackageoptions }}
-      - name: Create appdir.tar
-        run: tar -cvf appdir.tar appdir
-      - name: Upload ${{ matrix.profile }}-appdir
-        uses: actions/upload-artifact@v2
-        with:
-          name: ${{ matrix.profile }}-appdir
-          path: appdir.tar
-          if-no-files-found: error
-
-#
-# Debian Package
-#
-  deb:
-    name: Create Debian Package
-    needs: [buildkit, metadata]
-    runs-on: ubuntu-18.04
-    steps:
-      - uses: actions/checkout@v2
-      - name: install build tools
-        run: |
-          sudo apt-get update
-          sudo apt-get install debhelper devscripts
-      - name: Download linux-buildkit
-        uses: actions/download-artifact@v2
-        with:
-          name: linux-buildkit
-          path: pkgdir
-      - name: create orig.tar.gz with common/ libs/ mods/
-        run: |
-          cp -r dist/linux/common/ pkgdir
-          tar -cJf cryptomator_${{ needs.metadata.outputs.ppaVerStr }}.orig.tar.xz -C pkgdir .
-      - name: patch and rename pkgdir
-        run: |
-          cp -r dist/linux/debian/ pkgdir
-          export RFC2822_TIMESTAMP=`date --rfc-2822`
-          envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules
-          envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
-          find . -name "*.jar" >> pkgdir/debian/source/include-binaries
-          mv pkgdir cryptomator_${{ needs.metadata.outputs.ppaVerStr }}
-        env:
-          SEMVER_STR: ${{ needs.metadata.outputs.semVerStr }}
-          VERSION_NUM: ${{ needs.metadata.outputs.semVerNum }}
-          REVISION_NUM: ${{ needs.metadata.outputs.revNum }}
-          PPA_VERSION: ${{ needs.metadata.outputs.ppaVerStr }}-0ppa1
-      - name: import gpg key 615D449FE6E6A235
-        run: |
-          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
-          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign dist/linux/debian/rules
-        env:
-          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
-          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
-      - name: debuild
-        run: |
-          debuild -S -sa -d
-          debuild -b -sa -d
-        env:
-          DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
-          DEBSIGN_KEYID: 615D449FE6E6A235
-        working-directory: cryptomator_${{ needs.metadata.outputs.ppaVerStr }}
-      - name: Upload artifacts
-        uses: actions/upload-artifact@v2
-        with:
-          name: linux-deb-package
-          path: |
-            cryptomator_*.dsc
-            cryptomator_*.orig.tar.xz
-            cryptomator_*.debian.tar.xz
-            cryptomator_*_source.buildinfo
-            cryptomator_*_source.changes
-            cryptomator_*_amd64.deb
-
-#
-# Upload Source Package to PPA
-#
-  ppa:
-    name: Upload Source Package to PPA
-    needs: [deb]
-    runs-on: ubuntu-18.04
-    steps:
-      - name: install dput
-        run: |
-          sudo apt-get update
-          sudo apt-get install dput
-      - name: import public key
-        run: curl -sSL https://github.com/cryptobot.gpg | gpg --import -
-      - name: download linux-deb-package
-        uses: actions/download-artifact@v2
-        with:
-          name: linux-deb-package
-          path: .
-      - name: dput to beta repo
-        run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
-
-#
-# Linux Cryptomator.AppImage
-# 
-  linux-appimage:
-    name: Build Cryptomator.AppImage
-    runs-on: ubuntu-latest
-    needs: [appdir, metadata]
-    steps:
-      - uses: actions/checkout@v2
-      - name: Download linux-appdir
-        uses: actions/download-artifact@v2
-        with:
-          name: linux-appdir
-      - name: Untar appdir.tar
-        run: |
-          tar -xvf appdir.tar
-      - name: Patch Cryptomator.AppDir
-        run: |
-          mv appdir/Cryptomator Cryptomator.AppDir
-          cp -r dist/linux/appimage/resources/AppDir/* Cryptomator.AppDir/
-          envsubst '${REVISION_NO} ${SEMVER_STR}' < dist/linux/appimage/resources/AppDir/bin/cryptomator.sh > Cryptomator.AppDir/bin/cryptomator.sh
-          cp dist/linux/common/org.cryptomator.Cryptomator256.png Cryptomator.AppDir/usr/share/icons/hicolor/256x256/apps/org.cryptomator.Cryptomator.png
-          cp dist/linux/common/org.cryptomator.Cryptomator512.png Cryptomator.AppDir/usr/share/icons/hicolor/512x512/apps/org.cryptomator.Cryptomator.png
-          cp dist/linux/common/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg
-          cp dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.metainfo.xml
-          cp dist/linux/common/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/usr/share/applications/org.cryptomator.Cryptomator.desktop
-          cp dist/linux/common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
-          ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
-          ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
-          ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
-          ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
-          ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
-        env:
-          REVISION_NO: ${{ needs.metadata.outputs.revNum }}
-          SEMVER_STR: ${{ needs.metadata.outputs.semVerStr }}
-      - name: Extract libjffi.so # workaround for https://github.com/cryptomator/cryptomator-linux/issues/27
-        run: |
-          JFFI_NATIVE_JAR=`ls lib/app/ | grep -e 'jffi-[1-9]\.[0-9]\{1,2\}.[0-9]\{1,2\}-native.jar'`
-          ${JAVA_HOME}/bin/jar -xf lib/app/${JFFI_NATIVE_JAR} /jni/x86_64-Linux/
-          mv jni/x86_64-Linux/* lib/app/libjffi.so
-        working-directory: Cryptomator.AppDir
-      - name: Download AppImageKit
-        run: |
-          curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o appimagetool.AppImage
-          chmod +x appimagetool.AppImage
-          ./appimagetool.AppImage --appimage-extract
-      - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
-        run: |
-          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
-          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign Cryptomator.AppDir/AppRun
-        env:
-          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
-          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
-      - name: Build AppImage
-        run: >
-          ./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.metadata.outputs.semVerStr }}-x86_64.AppImage
-          -u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync'
-          --sign --sign-key=615D449FE6E6A235 --sign-args="--batch --pinentry-mode loopback"
-      - name: Upload AppImage
-        uses: actions/upload-artifact@v2
-        with:
-          name: linux-appimage
-          path: |
-            cryptomator-*.AppImage
-            cryptomator-*.AppImage.zsync
-          if-no-files-found: error
-
-#
-# macOS Cryptomator.app
-# 
-  mac-app:
-    name: Build Cryptomator.app
-    runs-on: macos-latest
-    needs: [appdir, metadata]
-    steps:
-      - uses: actions/checkout@v2
-      - name: Download mac-appdir
-        uses: actions/download-artifact@v2
-        with:
-          name: mac-appdir
-      - name: Untar appdir.tar
-        run: tar -xvf appdir.tar
-      - name: Patch Cryptomator.app
-        run: |
-          mv appdir/Cryptomator.app Cryptomator.app
-          mv dist/mac/resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/
-          sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
-          sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
-        env:
-          VERSION_NO: ${{ needs.metadata.outputs.semVerNum }}
-          REVISION_NO: ${{ needs.metadata.outputs.revNum }}
-      - name: Install codesign certificate
-        env:
-          CODESIGN_P12_BASE64: ${{ secrets.MACOS_CODESIGN_P12_BASE64 }}
-          CODESIGN_P12_PW: ${{ secrets.MACOS_CODESIGN_P12_PW }}
-          CODESIGN_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }}
-        run: |
-          # create variables
-          CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
-          KEYCHAIN_PATH=$RUNNER_TEMP/codesign.keychain-db
-
-          # import certificate and provisioning profile from secrets
-          echo -n "$CODESIGN_P12_BASE64" | base64 --decode --output $CERTIFICATE_PATH
-
-          # create temporary keychain
-          security create-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
-          security set-keychain-settings -lut 900 $KEYCHAIN_PATH
-          security unlock-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
-
-          # import certificate to keychain
-          security import $CERTIFICATE_PATH -P "$CODESIGN_P12_PW" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
-          security list-keychain -d user -s $KEYCHAIN_PATH
-      - name: Codesign
-        env:
-          CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
-        run: |
-          find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
-          for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
-            if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
-              JAR_FILENAME=$(basename ${JAR_PATH})
-              OUTPUT_PATH=${JAR_PATH%.*}
-              echo "Codesigning libs in ${JAR_FILENAME}..."
-              unzip -q ${JAR_PATH} -d ${OUTPUT_PATH}
-              find ${OUTPUT_PATH} -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
-              find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
-              rm ${JAR_PATH}
-              pushd ${OUTPUT_PATH} > /dev/null
-              zip -qr ../${JAR_FILENAME} *
-              popd > /dev/null
-              rm -r ${OUTPUT_PATH}
-            fi
-          done
-          echo "Codesigning Cryptomator.app..."
-          codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
-      - name: Clean up codesign certificate
-        if: ${{ always() }}
-        run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
-      - name: Create app.tar
-        run: tar -cvf app.tar Cryptomator.app
-      - name: Upload mac-app
-        uses: actions/upload-artifact@v2
-        with:
-          name: mac-app
-          path: app.tar
-          if-no-files-found: error
-
-#
-# macOS Cryptomator.dmg
-#
-  mac-dmg:
-    name: Build Cryptomator.dmg
-    runs-on: macos-11
-    needs: [mac-app, metadata]
-    steps:
-      - uses: actions/checkout@v2
-      - name: Download mac-appdir
-        uses: actions/download-artifact@v2
-        with:
-          name: mac-app
-      - name: Untar app.tar
-        run: tar -xvf app.tar
-      - name: Prepare .dmg contents
-        run: |
-          mkdir dmg
-          mv Cryptomator.app dmg
-          cp dist/mac/dmg/resources/macFUSE.webloc dmg
-          ls -l dmg
-      - name: Install create-dmg
-        run: |
-          brew install create-dmg
-          create-dmg --help
-      - name: Create .dmg
-        run: >
-          create-dmg
-          --volname Cryptomator
-          --volicon "dist/mac/dmg/resources/Cryptomator-Volume.icns"
-          --background "dist/mac/dmg/resources/Cryptomator-background.tiff"
-          --window-pos 400 100
-          --window-size 640 694
-          --icon-size 128
-          --icon "Cryptomator.app" 128 245
-          --hide-extension "Cryptomator.app"
-          --icon "macFUSE.webloc" 320 501
-          --hide-extension "macFUSE.webloc"
-          --app-drop-link 512 245
-          --eula "dist/mac/dmg/resources/license.rtf"
-          --icon ".background" 128 758
-          --icon ".fseventsd" 320 758
-          --icon ".VolumeIcon.icns" 512 758
-          Cryptomator-${VERSION_NO}.dmg dmg
-        env:
-          VERSION_NO: ${{ needs.metadata.outputs.semVerNum }}
-      - name: Install notarization credentials
-        env:
-          NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
-          NOTARIZATION_APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
-          NOTARIZATION_PW: ${{ secrets.MACOS_NOTARIZATION_PW }}
-          NOTARIZATION_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
-          NOTARIZATION_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_NOTARIZATION_TMP_KEYCHAIN_PW }}
-        run: |
-          # create temporary keychain
-          KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
-          security create-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
-          security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
-          security unlock-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
-
-          # import credentials from secrets
-          sudo xcode-select -s /Applications/Xcode_13.0.app
-          xcrun notarytool store-credentials "${NOTARIZATION_KEYCHAIN_PROFILE}" --apple-id "${NOTARIZATION_APPLE_ID}" --password "${NOTARIZATION_PW}" --team-id "${NOTARIZATION_TEAM_ID}" --keychain "${KEYCHAIN_PATH}"
-      - name: Notarize .dmg
-        env:
-          NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
-        run: |
-          KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
-          sudo xcode-select -s /Applications/Xcode_13.0.app
-          xcrun notarytool submit Cryptomator-*.dmg --keychain-profile "${NOTARIZATION_KEYCHAIN_PROFILE}" --keychain "${KEYCHAIN_PATH}" --wait
-          xcrun stapler staple Cryptomator-*.dmg
-      - name: Clean up notarization credentials
-        if: ${{ always() }}
-        run: security delete-keychain $RUNNER_TEMP/notarization.keychain-db
-      - name: Add possible alpha/beta tags to installer name
-        run: mv Cryptomator-*.dmg Cryptomator-${{ needs.metadata.outputs.semVerStr }}.dmg
-      - name: Upload mac-dmg
-        uses: actions/upload-artifact@v2
-        with:
-          name: mac-dmg
-          path: Cryptomator-*.dmg
-          if-no-files-found: error
-
-#
-# MSI package
-#
-  win-msi:
-    name: Build Cryptomator.msi
-    runs-on: windows-latest
-    needs: [appdir, metadata]
-    steps:
-      - uses: actions/checkout@v2
-      - name: Download win-appdir
-        uses: actions/download-artifact@v2
-        with:
-          name: win-appdir
-      - name: Untar appdir.tar
-        run: tar -xvf appdir.tar
-      - uses: actions/setup-java@v2
-        with:
-          distribution: 'temurin'
-          java-version: ${{ env.JAVA_VERSION }}
-          cache: 'maven'
-      - name: Patch Application Directory
-        run: |
-          cp dist/win/contrib/* appdir/Cryptomator
-      - name: Fix permissions
-        run: attrib -r appdir/Cryptomator/Cryptomator.exe
-        shell: pwsh
-      - name: Codesign
-        uses: skymatic/code-sign-action@v1
-        with:
-          certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
-          password: ${{ secrets.WIN_CODESIGN_P12_PW }}
-          certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
-          description: Cryptomator
-          timestampUrl: 'http://timestamp.digicert.com'
-          folder: appdir/Cryptomator
-          recursive: true
-      - name: Generate license
-        run: >
-          mvn -B license:add-third-party
-          "-Dlicense.thirdPartyFilename=license.rtf"
-          "-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl"
-          "-Dlicense.outputDirectory=dist/win/resources"
-      - name: Create MSI
-        run: >
-          ${JAVA_HOME}/bin/jpackage
-          --verbose
-          --type msi
-          --win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775
-          --app-image appdir/Cryptomator
-          --dest installer
-          --name Cryptomator
-          --vendor "Skymatic GmbH"
-          --copyright "(C) 2016 - 2022 Skymatic GmbH"
-          --app-version "${{ needs.metadata.outputs.semVerNum }}"
-          --win-menu
-          --win-dir-chooser
-          --win-shortcut-prompt
-          --win-update-url "https:\\cryptomator.org"
-          --win-menu-group Cryptomator
-          --resource-dir dist/win/resources
-          --license-file dist/win/resources/license.rtf
-          --file-associations dist/win/resources/FAvaultFile.properties
-        env:
-          JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
-      - name: Codesign MSI
-        uses: skymatic/code-sign-action@v1
-        with:
-          certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
-          password: ${{ secrets.WIN_CODESIGN_P12_PW }}
-          certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
-          description: Cryptomator Installer
-          timestampUrl: 'http://timestamp.digicert.com'
-          folder: installer
-      - name: Add possible alpha/beta tags to installer name
-        run: mv installer/Cryptomator-*.msi installer/Cryptomator-${{ needs.metadata.outputs.semVerStr }}-x64.msi
-      - name: Upload win-msi
-        uses: actions/upload-artifact@v2
-        with:
-          name: win-msi
-          path: installer/*.msi
-          if-no-files-found: error
-
-#
-# Windows Cryptomator.exe bundle
-#
-  win-exe:
-    name: Build Cryptomator.exe bundle
-    runs-on: windows-latest
-    needs: [win-msi, metadata]
-    steps:
-      - uses: actions/checkout@v2
-      - name: Download Windows msi
-        uses: actions/download-artifact@v2
-        with:
-          name: win-msi
-          path: dist/win/bundle/resources
-      - name: Strip version info from msi file name
-        run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
-      - uses: actions/setup-java@v2
-        with:
-          distribution: 'temurin'
-          java-version: ${{ env.JAVA_VERSION }}
-          cache: 'maven'
-      - name: Generate license
-        run: >
-          mvn -B license:add-third-party
-          "-Dlicense.thirdPartyFilename=license.rtf"
-          "-Dlicense.fileTemplate=dist/win/bundle/resources/licenseTemplate.ftl"
-          "-Dlicense.outputDirectory=dist/win/bundle/resources"
-      - name: Download winfsp
-        run:
-          curl --output dist/win/bundle/resources/winfsp.msi -L https://github.com/winfsp/winfsp/releases/download/v1.10/winfsp-1.10.22006.msi
-      - name: Compile to wixObj file
-        run: >
-          "${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
-          -ext WixBalExtension
-          -out dist/win/bundle/
-          -dBundleVersion="${{ needs.metadata.outputs.semVerNum }}.${{ needs.metadata.outputs.revNum }}"
-          -dBundleVendor="Skymatic GmbH"
-          -dBundleCopyright="(C) 2016 - 2022 Skymatic GmbH"
-          -dAboutUrl="https://cryptomator.org"
-          -dHelpUrl="https://cryptomator.org/contact"
-          -dUpdateUrl="https://cryptomator.org/downloads/"
-      - name: Create executable with linker
-        run: >
-          "${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
-          -ext WixBalExtension
-          -out installer/Cryptomator.exe
-      - name: Codesign EXE
-        uses: skymatic/code-sign-action@v1
-        with:
-          certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
-          password: ${{ secrets.WIN_CODESIGN_P12_PW }}
-          certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
-          description: Cryptomator Installer
-          timestampUrl: 'http://timestamp.digicert.com'
-          folder: installer
-      - name: Add possible alpha/beta tags to installer name
-        run: mv installer/Cryptomator.exe installer/Cryptomator-${{ needs.metadata.outputs.semVerStr }}-x64.exe
-      - name: Upload win-exe
-        uses: actions/upload-artifact@v2
-        with:
-          name: win-exe
-          path: installer/*.exe
-          if-no-files-found: error
-
-#
-# Release
-#
-  release:
-    name: Draft a release on Github
-    runs-on: ubuntu-latest
-    needs: [metadata,linux-appimage,mac-dmg,win-msi,win-exe,ppa]
-    if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
-    steps:
-      - uses: actions/checkout@v2
-      - name: Create tarball
-        run: git archive --prefix="cryptomator-${{ needs.metadata.outputs.semVerStr }}/" -o "cryptomator-${{ needs.metadata.outputs.semVerStr }}.tar.gz" ${{ github.ref }}
-      - name: Download Debian package
-        uses: actions/download-artifact@v2
-        with:
-          name: linux-deb-package
-      - name: Download linux appimage
-        uses: actions/download-artifact@v2
-        with:
-          name: linux-appimage
-      - name: Download macOS dmg
-        uses: actions/download-artifact@v2
-        with:
-          name: mac-dmg
-      - name: Download Windows msi
-        uses: actions/download-artifact@v2
-        with:
-          name: win-msi
-      - name: Download Windows exe
-        uses: actions/download-artifact@v2
-        with:
-          name: win-exe
-      - name: Create detached GPG signature for all release files with key 615D449FE6E6A235
-        run: |
-          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
-          for FILE in `find . -name "*.AppImage" -o -name "*.deb" -o -name "*.dmg" -o -name "*.exe" -o -name "*.msi" -o -name "*.zsync" -o -name "*.tar.gz"`; do
-            echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a ${FILE}
-          done
-        env:
-          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
-          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
-      - name: Compute SHA256 checksums of release artifacts
-        run: |
-          SHA256_SUMS=`find . -name "*.AppImage" -o -name "*.deb" -o -name "*.dmg" -o -name "*.exe" -o -name "*.msi" -o -name "*.tar.gz" | xargs sha256sum`
-          echo "SHA256_SUMS<<EOF" >> $GITHUB_ENV
-          echo "${SHA256_SUMS}" >> $GITHUB_ENV
-          echo "EOF" >> $GITHUB_ENV
-        continue-on-error: true
-      - name: Create release draft
-        uses: softprops/action-gh-release@v1
-        with:
-          draft: true
-          fail_on_unmatched_files: true
-          discussion_category_name: releases
-          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
-          files: |
-            *.AppImage
-            *.zsync
-            *.asc
-            *.deb
-            *.dmg
-            *.msi
-            *.exe
-          body: |-
-            :construction: Work in Progress
-            ## What's New
-            ## Bugfixes
-            ## Misc
-            
-            ---
-            
-            :scroll: A complete list of closed issues is available [here](LINK).
-            
-            ---
-            
-            :floppy_disk: SHA-256 checksums of release artifacts:
-            ```
-            ${{ env.SHA256_SUMS }}
-            ```

+ 255 - 0
.github/workflows/win-exe.yml

@@ -0,0 +1,255 @@
+name: Build Windows Installer
+
+on:
+  release:
+    types: [published]
+  workflow_dispatch:
+
+env:
+  JAVA_VERSION: 17
+  WINFSP_MSI: https://github.com/winfsp/winfsp/releases/download/v1.10/winfsp-1.10.22006.msi
+
+defaults:
+  run:
+    shell: bash
+
+jobs:
+  build-msi:
+    name: Build .msi Installer
+    runs-on: windows-latest
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Setup Java
+        uses: actions/setup-java@v2
+        with:
+          distribution: 'temurin'
+          java-version: ${{ env.JAVA_VERSION }}
+          cache: 'maven'
+      - id: versions 
+        name: Apply version information
+        run: |
+          if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then
+            SEM_VER_STR=${GITHUB_REF##*/}
+            mvn versions:set -DnewVersion=${SEM_VER_STR}
+          else
+            SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
+          fi
+          SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
+          REVCOUNT=`git rev-list --count HEAD`
+          echo "::set-output name=semVerStr::${SEM_VER_STR}"
+          echo "::set-output name=semVerNum::${SEM_VER_NUM}"
+          echo "::set-output name=revNum::${REVCOUNT}"
+      - name: Validate Version
+        uses: skymatic/semver-validation-action@v1
+        with:
+          version: ${{ steps.versions.outputs.semVerStr }}
+      - name: Run maven
+        run: mvn -B clean package -Pdependency-check,win -DskipTests
+      - name: Patch target dir
+        run: |
+          cp LICENSE.txt target
+          cp dist/linux/launcher.sh target
+          cp target/cryptomator-*.jar target/mods
+      - name: Run jlink
+        run: >
+          ${JAVA_HOME}/bin/jlink
+          --verbose
+          --output runtime
+          --module-path "${JAVA_HOME}/jmods"
+          --add-modules java.base,java.desktop,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
+          --strip-native-commands
+          --no-header-files
+          --no-man-pages
+          --strip-debug
+          --compress=1
+      - name: Run jpackage
+        run: >
+          ${JAVA_HOME}/bin/jpackage
+          --verbose
+          --type app-image
+          --runtime-image runtime
+          --input target/libs
+          --module-path target/mods
+          --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+          --dest appdir
+          --name Cryptomator
+          --vendor "Skymatic GmbH"
+          --copyright "(C) 2016 - 2022 Skymatic GmbH"
+          --app-version "${{ steps.versions.outputs.semVerNum }}.${{ steps.versions.outputs.revNum }}"
+          --java-options "-Xss5m"
+          --java-options "-Xmx256m"
+          --java-options "-Dfile.encoding=\"utf-8\""
+          --java-options "-Dcryptomator.logDir=\"~/AppData/Roaming/Cryptomator\""
+          --java-options "-Dcryptomator.pluginDir=\"~/AppData/Roaming/Cryptomator/Plugins\""
+          --java-options "-Dcryptomator.settingsPath=\"~/AppData/Roaming/Cryptomator/settings.json\""
+          --java-options "-Dcryptomator.ipcSocketPath=\"~/AppData/Roaming/Cryptomator/ipc.socket\""
+          --java-options "-Dcryptomator.keychainPath=\"~/AppData/Roaming/Cryptomator/keychain.json\""
+          --java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\""
+          --java-options "-Dcryptomator.showTrayIcon=true"
+          --java-options "-Dcryptomator.buildNumber=\"msi-${{ steps.versions.outputs.revNum }}\""
+          --resource-dir dist/win/resources
+          --icon dist/win/resources/Cryptomator.ico
+      - name: Patch Application Directory
+        run: |
+          cp dist/win/contrib/* appdir/Cryptomator
+      - name: Fix permissions
+        run: attrib -r appdir/Cryptomator/Cryptomator.exe
+        shell: pwsh
+      - name: Codesign
+        uses: skymatic/code-sign-action@v1
+        with:
+          certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
+          password: ${{ secrets.WIN_CODESIGN_P12_PW }}
+          certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
+          description: Cryptomator
+          timestampUrl: 'http://timestamp.digicert.com'
+          folder: appdir/Cryptomator
+          recursive: true
+      - name: Generate license
+        run: >
+          mvn -B license:add-third-party
+          "-Dlicense.thirdPartyFilename=license.rtf"
+          "-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl"
+          "-Dlicense.outputDirectory=dist/win/resources"
+      - name: Create MSI
+        run: >
+          ${JAVA_HOME}/bin/jpackage
+          --verbose
+          --type msi
+          --win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775
+          --app-image appdir/Cryptomator
+          --dest installer
+          --name Cryptomator
+          --vendor "Skymatic GmbH"
+          --copyright "(C) 2016 - 2022 Skymatic GmbH"
+          --app-version "${{ steps.versions.outputs.semVerNum }}"
+          --win-menu
+          --win-dir-chooser
+          --win-shortcut-prompt
+          --win-update-url "https:\\cryptomator.org"
+          --win-menu-group Cryptomator
+          --resource-dir dist/win/resources
+          --license-file dist/win/resources/license.rtf
+          --file-associations dist/win/resources/FAvaultFile.properties
+        env:
+          JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
+      - name: Codesign MSI
+        uses: skymatic/code-sign-action@v1
+        with:
+          certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
+          password: ${{ secrets.WIN_CODESIGN_P12_PW }}
+          certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
+          description: Cryptomator Installer
+          timestampUrl: 'http://timestamp.digicert.com'
+          folder: installer
+      - name: Add possible alpha/beta tags to installer name
+        run: mv installer/Cryptomator-*.msi Cryptomator-${{ steps.versions.outputs.semVerStr }}-x64.msi
+      - name: Create detached GPG signature with key 615D449FE6E6A235
+        run: |
+          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
+          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a Cryptomator-*.msi
+        env:
+          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
+          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: msi
+          path: |
+            Cryptomator-*.msi
+            Cryptomator-*.asc
+          if-no-files-found: error
+      - name: Publish .msi on GitHub Releases
+        if: startsWith(github.ref, 'refs/tags/')
+        uses: softprops/action-gh-release@v1
+        with:
+          fail_on_unmatched_files: true
+          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+          files: |
+            *.msi
+            *.asc
+    outputs:
+      semVerNum: ${{ steps.versions.outputs.semVerNum }}
+      semVerStr: ${{ steps.versions.outputs.semVerStr }}
+      revNum: ${{ steps.versions.outputs.revNum }}
+
+  build-exe:
+    name: Build .exe installer
+    runs-on: windows-latest
+    needs: [build-msi]
+    steps:
+      - uses: actions/checkout@v2
+      - name: Download .msi
+        uses: actions/download-artifact@v2
+        with:
+          name: msi
+          path: dist/win/bundle/resources
+      - name: Strip version info from msi file name
+        run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
+      - uses: actions/setup-java@v2
+        with:
+          distribution: 'temurin'
+          java-version: ${{ env.JAVA_VERSION }}
+          cache: 'maven'
+      - name: Generate license
+        run: >
+          mvn -B license:add-third-party
+          "-Dlicense.thirdPartyFilename=license.rtf"
+          "-Dlicense.fileTemplate=dist/win/bundle/resources/licenseTemplate.ftl"
+          "-Dlicense.outputDirectory=dist/win/bundle/resources"
+      - name: Download WinFsp
+        run:
+          curl --output dist/win/bundle/resources/winfsp.msi -L ${{ env.WINFSP_MSI }}
+      - name: Compile to wixObj file
+        run: >
+          "${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
+          -ext WixBalExtension
+          -out dist/win/bundle/
+          -dBundleVersion="${{ needs.build-msi.outputs.semVerNum }}.${{ needs.build-msi.outputs.revNum }}"
+          -dBundleVendor="Skymatic GmbH"
+          -dBundleCopyright="(C) 2016 - 2022 Skymatic GmbH"
+          -dAboutUrl="https://cryptomator.org"
+          -dHelpUrl="https://cryptomator.org/contact"
+          -dUpdateUrl="https://cryptomator.org/downloads/"
+      - name: Create executable with linker
+        run: >
+          "${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
+          -ext WixBalExtension
+          -out installer/Cryptomator.exe
+      - name: Codesign EXE
+        uses: skymatic/code-sign-action@v1
+        with:
+          certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
+          password: ${{ secrets.WIN_CODESIGN_P12_PW }}
+          certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
+          description: Cryptomator Installer
+          timestampUrl: 'http://timestamp.digicert.com'
+          folder: installer
+      - name: Add possible alpha/beta tags to installer name
+        run: mv installer/Cryptomator.exe Cryptomator-${{ needs.build-msi.outputs.semVerStr }}-x64.exe
+      - name: Create detached GPG signature with key 615D449FE6E6A235
+        run: |
+          echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
+          echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a Cryptomator-*.exe
+        env:
+          GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
+          GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: exe
+          path: |
+            Cryptomator-*.exe
+            Cryptomator-*.asc
+          if-no-files-found: error
+      - name: Publish .msi on GitHub Releases
+        if: startsWith(github.ref, 'refs/tags/')
+        uses: softprops/action-gh-release@v1
+        with:
+          fail_on_unmatched_files: true
+          token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+          files: |
+            *.exe
+            *.asc