diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cdbfc23cd..7027c9ddf 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -60,7 +60,7 @@ jobs: --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 + --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 --strip-native-commands --no-header-files --no-man-pages @@ -92,6 +92,7 @@ jobs: --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.p12Path=\"~/.config/Cryptomator/key.p12\"" --java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\"" --java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\"" --java-options "-Dcryptomator.showTrayIcon=false" diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index fb8b3a423..6f43b5155 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -111,7 +111,7 @@ jobs: cryptomator_*_amd64.deb cryptomator_*.asc - name: Publish on PPA - if: startsWith(github.ref, 'refs/tags/') || github.event.inputs.dput == 'true' + if: startsWith(github.ref, 'refs/tags/') || inputs.dput run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes - name: Publish Debian package on GitHub Releases if: startsWith(github.ref, 'refs/tags/') diff --git a/.github/workflows/dl-stats.yml b/.github/workflows/dl-stats.yml new file mode 100644 index 000000000..0d9ca5dd7 --- /dev/null +++ b/.github/workflows/dl-stats.yml @@ -0,0 +1,63 @@ +name: Report Download Stats + +on: + schedule: + - cron: '0/15 * * * *' # run every 15 min - don't forget to adjust the "interval" in the json sent to the metrics endpoint + +jobs: + report-download-stats: + runs-on: ubuntu-latest + steps: + - name: Get download count of latest releases + id: get-stats + uses: actions/github-script@v6 + with: + script: | + const query = `query($owner:String!, $name:String!) { + repository(owner:$owner, name:$name){ + releases(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) { + nodes { + isPrerelease + tagName + releaseAssets(first: 20) { + nodes { + name + downloadCount + } + } + } + } + } + }`; + const variables = { + owner: context.repo.owner, + name: context.repo.repo + } + return await github.graphql(query, variables) + - name: Transform Results + id: transform-stats + run: | + TIME=$(($(date +%s) / $INTERVAL * $INTERVAL)) + echo ${JSON_DATA} | jq --arg TIME "$TIME" --arg INTERVAL "$INTERVAL" -c '.repository.releases.nodes[] | select(.isPrerelease == false) | .tagName as $tagName | .releaseAssets.nodes[] | {filename: .name, downloads: .downloadCount, release: $tagName, time: ($TIME|tonumber), interval: ($INTERVAL|tonumber)}' > input.json + + jq -c 'select(.filename|endswith("-x86_64.AppImage")) | {name: "github.releases.downloads", tags: ["file=AppImage", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json + jq -c 'select(.filename|endswith("_amd64.deb")) | {name: "github.releases.downloads", tags: ["file=deb", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json + jq -c 'select(.filename|endswith("-x64.msi")) | {name: "github.releases.downloads", tags: ["file=msi", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json + jq -c 'select(.filename|endswith("-x64.exe")) | {name: "github.releases.downloads", tags: ["file=exe", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json + jq -c 'select(.filename|endswith("-arm64.dmg")) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=arm64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json + jq -c 'select(.filename|endswith(".dmg")) | select(.filename|endswith("-arm64.dmg")|not) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json + + RESULT=$(jq -s -c "." output.json) + echo "::set-output name=result::${RESULT}" + env: + INTERVAL: 900 + JSON_DATA: ${{ steps.get-stats.outputs.result }} + - name: Upload Results + uses: fjogeleit/http-request-action@v1 + with: + url: 'https://graphite-us-central1.grafana.net/metrics' + method: 'POST' + contentType: 'application/json' + bearerToken: ${{ secrets.GRAFANA_GRAPHITE_TOKEN }} + data: ${{ steps.transform-stats.outputs.result }} + continue-on-error: true # currently there seems to be a problem with the metrics endpoint, failing every now and then diff --git a/.github/workflows/error-db.yml b/.github/workflows/error-db.yml new file mode 100644 index 000000000..09a15fe1f --- /dev/null +++ b/.github/workflows/error-db.yml @@ -0,0 +1,60 @@ +name: Update Error Database + +on: + discussion: + types: [created, edited, category_changed, answered, unanswered] + discussion_comment: + types: [created, edited, deleted] + +jobs: + update-error-db: + runs-on: ubuntu-latest + if: github.event.discussion.category.name == 'Errors' + steps: + - name: Query Discussion Data + id: query-data + uses: actions/github-script@v6 + with: + script: | + const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) { + repository(owner: $owner, name: $name) { + discussion(number: $discussionNumber) { + id + upvoteCount + title + url + answer { + url + upvoteCount + } + comments { + totalCount + } + } + } + }`; + const variables = { + owner: context.repo.owner, + name: context.repo.repo, + discussionNumber: context.payload.discussion.number + } + return await github.graphql(query, variables) + - name: Get Gist + id: get-gist + uses: andymckay/get-gist-action@master + with: + gistURL: https://gist.github.com/cryptobot/accba9fb9555e7192271b85606f97230 + - name: Merge Error Code Data + run: | + jq -c '.' ${{ steps.get-gist.outputs.file }} > original.json + echo $DISCUSSION | jq -c '.repository.discussion | .comments = .comments.totalCount | {(.id|tostring) : .}' > new.json + jq -s '.[0] * .[1]' original.json new.json > merged.json + env: + DISCUSSION: ${{ steps.query-data.outputs.result }} + - name: Patch Gist + uses: exuanbo/actions-deploy-gist@v1 + with: + token: ${{ secrets.CRYPTOBOT_GIST_TOKEN }} + gist_id: accba9fb9555e7192271b85606f97230 + gist_file_name: errorcodes.json + file_path: merged.json diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index 833acac61..1ba5822e3 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -60,7 +60,7 @@ jobs: --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 + --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 --strip-native-commands --no-header-files --no-man-pages @@ -89,7 +89,9 @@ jobs: --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.p12Path=\"~/Library/Application Support/Cryptomator/key.p12\"" --java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\"" + --java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\"" --java-options "-Dcryptomator.showTrayIcon=true" --java-options "-Dcryptomator.buildNumber=\"dmg-${{ steps.versions.outputs.revNum }}\"" --mac-package-identifier org.cryptomator @@ -187,33 +189,14 @@ jobs: 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 }} + 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 }} - 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 @@ -227,10 +210,6 @@ jobs: 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: diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 3a9ed8ab0..245aa570e 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -8,10 +8,14 @@ on: version: description: 'Version' required: false + winget-release: + description: 'Release artifacts to winget' + required: true + type: boolean + default: false env: JAVA_VERSION: 17 - WINFSP_MSI: https://github.com/winfsp/winfsp/releases/download/v1.10/winfsp-1.10.22006.msi defaults: run: @@ -65,7 +69,7 @@ jobs: --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 + --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 --strip-native-commands --no-header-files --no-man-pages @@ -92,11 +96,13 @@ jobs: --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.p12Path=\"~/AppData/Roaming/Cryptomator/key.p12\"" --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 }}\"" + --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\"" + --java-options "-Dcryptomator.integrationsWin.keychainPaths=\"~/AppData/Roaming/Cryptomator/keychain.json\"" --resource-dir dist/win/resources --icon dist/win/resources/Cryptomator.ico - name: Patch Application Directory @@ -110,7 +116,7 @@ jobs: with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} - certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B + certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A description: Cryptomator timestampUrl: 'http://timestamp.digicert.com' folder: appdir/Cryptomator @@ -153,7 +159,7 @@ jobs: with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} - certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B + certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A description: Cryptomator Installer timestampUrl: 'http://timestamp.digicert.com' folder: installer @@ -188,6 +194,20 @@ jobs: semVerStr: ${{ steps.versions.outputs.semVerStr }} revNum: ${{ steps.versions.outputs.revNum }} + publish-winget: + name: Publish on winget repo + runs-on: windows-latest + needs: [build-msi] + if: github.event.action == 'release' || inputs.winget-release + steps: + - name: Submit package to Windows Package Manager Community Repository + run: | + iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe + $github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json + $installerUrl = $github.release.assets | Where-Object -Property name -match 'Cryptomator-*.msi' | Select -ExpandProperty browser_download_url -First 1 + .\wingetcreate.exe update Cryptomator.Cryptomator -s -v $github.release.tag_name -u $installerUrl -t ${{ secrets.CRYPTOBOT_WINGET_TOKEN }} + shell: pwsh + build-exe: name: Build .exe installer runs-on: windows-latest @@ -218,8 +238,10 @@ jobs: "-Dlicense.licenseMergesUrl=file:///${{ github.workspace }}/license/merges" shell: pwsh - name: Download WinFsp - run: - curl --output dist/win/bundle/resources/winfsp.msi -L ${{ env.WINFSP_MSI }} + run: | + $winfspUrl= (Select-String -Path ".\dist\win\bundle\resources\winfsp-download.url" -Pattern 'https:.*').Matches.Value + curl --output dist/win/bundle/resources/winfsp.msi -L $winfspUrl + shell: pwsh - name: Compile to wixObj file run: > "${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs @@ -246,7 +268,7 @@ jobs: with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} - certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B + certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A description: Cryptomator Installer timestampUrl: 'http://timestamp.digicert.com' folder: tmp @@ -260,7 +282,7 @@ jobs: with: certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} password: ${{ secrets.WIN_CODESIGN_P12_PW }} - certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B + certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A description: Cryptomator Installer timestampUrl: 'http://timestamp.digicert.com' folder: installer diff --git a/.gitignore b/.gitignore index 5c84c0dfb..796458fe6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,25 +5,9 @@ *.war *.ear -# Eclipse Settings Files # -.settings -.project -.classpath - # Maven # target/ pom.xml.versionsBackup -# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) # -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/shelf -.idea/dictionaries/** -!.idea/dictionaries/dict_* -.idea/compiler.xml -.idea/jarRepositories.xml -.idea/uiDesigner.xml -.idea/**/libraries/ -*.iml - +# Java Crash Logs hs_err_pid*.log \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..8e78cfe58 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,13 @@ +# see https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems + +# Default ignored files +/shelf/ +/workspace.xml +/usage.statistics.xml +/dictionaries/ + +# generated from Maven +/jarRepositories.xml +/modules.xml +/*.iml +/libraries/*.xml \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 000000000..18be437d6 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Cryptomator_Linux.xml b/.idea/runConfigurations/Cryptomator_Linux.xml index 81c2da004..6378f9a00 100644 --- a/.idea/runConfigurations/Cryptomator_Linux.xml +++ b/.idea/runConfigurations/Cryptomator_Linux.xml @@ -2,7 +2,7 @@