name: Build macOS .dmg for x64 ####################################### # STOP! DO NOT EDIT THIS FILE! # # It is a copy of mac-dmg.yml with tiny adjustements (mainly lines 42 to 47) # It was made necessary, since Github does not offer free macos intel runners for macos 15 and above. # This workflow can only be triggered by a release. # ####################################### on: release: types: [published] env: JAVA_DIST: 'temurin' JAVA_VERSION: '23.0.1+11' jobs: get-version: uses: ./.github/workflows/get-version.yml with: version: ${{ inputs.version }} build-arm: name: Build Cryptomator.app for ${{ matrix.output-suffix }} runs-on: ${{ matrix.os }} needs: [get-version] strategy: fail-fast: false matrix: include: - os: macos-15-large architecture: x64 output-suffix: x64 fuse-lib: macFUSE openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_osx-x64_bin-jmods.zip' openjfx-sha: '115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4' steps: - uses: actions/checkout@v4 - name: Setup Java uses: actions/setup-java@v4 with: distribution: ${{ env.JAVA_DIST }} java-version: ${{ env.JAVA_VERSION }} architecture: ${{ matrix.architecture }} check-latest: true cache: 'maven' - name: Download OpenJFX jmods id: download-jmods run: | curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip echo "${{ matrix.openjfx-sha }} *openjfx-jmods.zip" | shasum -a256 --check mkdir -p openjfx-jmods/ unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods - name: Ensure major jfx version in pom and in jmods is the same run: | JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1) JMOD_VERSION=${JMOD_VERSION#*@} JMOD_VERSION=${JMOD_VERSION%%.*} POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) POM_JFX_VERSION=${POM_JFX_VERSION#*@} POM_JFX_VERSION=${POM_JFX_VERSION%%.*} if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})" exit 1 fi - name: Set version run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} - name: Run maven run: mvn -B -Djavafx.platform=mac clean package -Pmac -DskipTests - name: Patch target dir run: | cp LICENSE.txt target cp target/cryptomator-*.jar target/mods - name: Run jlink #Remark: no compression is applied for improved build compression later (here dmg) run: > ${JAVA_HOME}/bin/jlink --verbose --output runtime --module-path "${JAVA_HOME}/jmods:openjfx-jmods" --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler --strip-native-commands --no-header-files --no-man-pages --strip-debug --compress zip-0 - 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 - 2025 Skymatic GmbH" --app-version "${{ needs.get-version.outputs.semVerNum }}" --java-options "--enable-preview" --java-options "--enable-native-access=org.cryptomator.jfuse.mac" --java-options "-Xss5m" --java-options "-Xmx256m" --java-options "-Dfile.encoding=\"utf-8\"" --java-options "-Djava.net.useSystemProxies=true" --java-options "-Dapple.awt.enableTemplateImages=true" --java-options "-Dsun.java2d.metal=true" --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/Cryptomator\"" --java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/Cryptomator/Plugins\"" --java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/Cryptomator/settings.json\"" --java-options "-Dcryptomator.p12Path=\"@{userhome}/Library/Application Support/Cryptomator/key.p12\"" --java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/Cryptomator/ipc.socket\"" --java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\"" --java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\"" --java-options "-Dcryptomator.showTrayIcon=true" --java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.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 echo -n "$PROVISIONING_PROFILE_BASE64" | base64 --decode --output Cryptomator.app/Contents/embedded.provisionprofile env: VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} REVISION_NO: ${{ needs.get-version.outputs.revNum }} PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }} - name: Generate license for dmg run: > mvn -B -Djavafx.platform=mac license:add-third-party -Dlicense.thirdPartyFilename=license.rtf -Dlicense.outputDirectory=dist/mac/dmg/resources -Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl -Dlicense.includedScopes=compile -Dlicense.excludedGroups=^org\.cryptomator -Dlicense.failOnMissing=true -Dlicense.licenseMergesUrl=file://${{ github.workspace }}/license/merges - 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: | echo "Codesigning jdk files..." find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; find Cryptomator.app/Contents/runtime/Contents/Home/lib/ \( -name 'jspawnhelper' -o -name 'pauseengine' -o -name 'simengine' \) -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \; echo "Codesigning jar contents..." 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..." sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" dist/mac/Cryptomator.entitlements sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" dist/mac/Cryptomator.entitlements codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app env: CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }} TEAM_IDENTIFIER: ${{ secrets.MACOS_TEAM_IDENTIFIER }} - name: Prepare .dmg contents run: | mkdir dmg mv Cryptomator.app dmg cp dist/mac/dmg/resources/${{ matrix.fuse-lib }}.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-${{ matrix.fuse-lib }}-background.tiff" --window-pos 400 100 --window-size 640 694 --icon-size 128 --icon "Cryptomator.app" 128 245 --hide-extension "Cryptomator.app" --icon "${{ matrix.fuse-lib }}.webloc" 320 501 --hide-extension "${{ matrix.fuse-lib }}.webloc" --app-drop-link 512 245 --eula "dist/mac/dmg/resources/license.rtf" --icon ".background" 128 758 --icon ".VolumeIcon.icns" 512 758 Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg env: VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} - name: Notarize .dmg if: startsWith(github.ref, 'refs/tags/') || inputs.notarize uses: cocoalibs/xcode-notarization-action@v1 with: app-path: 'Cryptomator-*.dmg' apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }} password: ${{ secrets.MACOS_NOTARIZATION_PW }} team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} xcode-path: '/Applications/Xcode_16.app' - name: Add possible alpha/beta tags to installer name run: mv Cryptomator-*.dmg Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.output-suffix }}.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: Upload artifacts uses: actions/upload-artifact@v4 with: name: dmg-${{ matrix.output-suffix }} path: | Cryptomator-*.dmg Cryptomator-*.asc if-no-files-found: error - name: Publish dmg on GitHub Releases if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published' uses: softprops/action-gh-release@v2 with: fail_on_unmatched_files: true token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} files: | Cryptomator-*.dmg Cryptomator-*.asc