diff --git a/.docs/Troubleshooting.md b/.docs/Troubleshooting.md index 76e206a3..024a8dbb 100644 --- a/.docs/Troubleshooting.md +++ b/.docs/Troubleshooting.md @@ -146,6 +146,12 @@ Red Hat: `cert-sync --user /etc/pki/tls/certs/ca-bundle.crt` If it still doesn't work, try mozroots: `mozroots --import --ask-remove` +## macOS-specific + +### DiscordChatExporter is damaged and can’t be opened. You should move it to the Trash. + +Check the [Using the GUI page](Using-the-GUI.md#step-1) for instructions on how to run the app. + --- > ❓ If you still have unanswered questions, feel free to [create a new discussion](https://github.com/Tyrrrz/DiscordChatExporter/discussions/new). diff --git a/.docs/Using-the-GUI.md b/.docs/Using-the-GUI.md index 27417f72..d175765b 100644 --- a/.docs/Using-the-GUI.md +++ b/.docs/Using-the-GUI.md @@ -10,7 +10,22 @@ ### Step 1 -After extracting the `.zip`, run `DiscordChatExporter.exe` (Windows), or `DiscordChatExporter` (Mac OS and Linux). +After extracting the `.zip`, run `DiscordChatExporter.exe` **(Windows)**, or `DiscordChatExporter` **(Linux)**. + +If you're using **macOS**, you'll need to manually grant permission for the app to run. +If you skip these steps, the "DiscordChatExporter is damaged and can’t be opened" error will be shown. + +1. Open Terminal.app. You can search for it in Spotlight (press + Space and type "Terminal"). +2. Paste the following into the terminal window: + ```bash + xattr -rd com.apple.quarantine + ``` +3. Hit Space once to add a space after the command +4. Drag and drop DiscordChatExporter.app into the terminal window +5. Press Return to run the command +6. Open DiscordChatExporter.app normally + +> Apple requires apps to be notarized and signed in order to run on macOS without warnings, which in turn requires an Apple Developer membership ($99/year). This open-source project is distributed for free and without commercial intent. ### Step 2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5bea0629..cb5e2054 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -138,6 +138,16 @@ jobs: --runtime ${{ matrix.rid }} --self-contained + - name: Generate macOS .app bundle resources + if: ${{ startsWith(matrix.rid, 'osx-') && matrix.app == 'DiscordChatExporter.Gui' }} + shell: pwsh + run: > + ./bundle-macos-app.ps1 + -BundleName "${{ matrix.asset }}" + -PublishDir "${{ matrix.app }}/bin/publish/" + -Version "${{ github.ref_type == 'tag' && github.ref_name || '999.9.9'}}" + -GitHubSha "${{ github.sha }}" + - name: Upload artifacts uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: @@ -210,9 +220,13 @@ jobs: path: ${{ matrix.app }}/ - name: Set permissions - if: ${{ !startsWith(matrix.rid, 'win-') }} + if: ${{ !startsWith(matrix.rid, 'win-') && !(startsWith(matrix.rid, 'osx-') && matrix.app == 'DiscordChatExporter.Gui') }} run: chmod +x ${{ matrix.app }}/${{ matrix.asset }} + - name: Set permissions for macOS .app bundle + if: ${{ startsWith(matrix.rid, 'osx-') && matrix.app == 'DiscordChatExporter.Gui' }} + run: chmod +x ${{ matrix.app }}/${{ matrix.asset }}.app/Contents/MacOS/${{ matrix.asset }} + - name: Create package # Change into the artifacts directory to avoid including the directory itself in the zip archive working-directory: ${{ matrix.app }}/ diff --git a/bundle-macos-app.ps1 b/bundle-macos-app.ps1 new file mode 100644 index 00000000..343cdfd4 --- /dev/null +++ b/bundle-macos-app.ps1 @@ -0,0 +1,71 @@ +param( + [Parameter(Mandatory=$true)] + [string]$BundleName, + + [Parameter(Mandatory=$true)] + [string]$PublishDir, + + [Parameter(Mandatory=$true)] + [string]$Version, + + [Parameter(Mandatory=$true)] + [string]$GitHubSha +) + +# Setup paths +$appName = "$BundleName.app" +$appDir = Join-Path "bundle-macos-app-staging" $appName +$contentsDir = Join-Path $appDir "Contents" +$macosDir = Join-Path $contentsDir "MacOS" +$resourcesDir = Join-Path $contentsDir "Resources" + +# Create the macOS .app bundle directory structure +New-Item -ItemType Directory -Path $macosDir -Force +New-Item -ItemType Directory -Path $resourcesDir -Force + +# Copy icon into the .app's Resources folder +Copy-Item -Path "favicon.icns" -Destination (Join-Path $resourcesDir "AppIcon.icns") -Force + +# Generate Info.plist metadata file with app information +$plistContent = @" + + + + + CFBundleDisplayName + $BundleName + CFBundleName + $BundleName + CFBundleExecutable + $BundleName + NSHumanReadableCopyright + © Oleksii Holub + CFBundleIdentifier + me.Tyrrrz.$BundleName + CFBundleSpokenName + Discord Chat Exporter + CFBundleIconFile + AppIcon + CFBundleIconName + AppIcon + CFBundleVersion + $GitHubSha + CFBundleShortVersionString + $Version + NSHighResolutionCapable + + CFBundlePackageType + APPL + + +"@ + +Set-Content -Path (Join-Path $contentsDir "Info.plist") -Value $plistContent + +# Move all files from the publish directory into the MacOS directory +Get-ChildItem -Path $PublishDir | ForEach-Object { + Move-Item -Path $_.FullName -Destination $macosDir -Force +} + +# Move the final .app bundle into the publish directory for upload +Move-Item -Path $appDir -Destination $PublishDir -Force \ No newline at end of file diff --git a/favicon.icns b/favicon.icns new file mode 100644 index 00000000..85a0d257 Binary files /dev/null and b/favicon.icns differ