From d0dd3d4d8bfb111e802017239e429170f4695bc8 Mon Sep 17 00:00:00 2001 From: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com> Date: Sun, 28 Apr 2024 19:55:52 +0300 Subject: [PATCH] Make the app x-platform (#436) --- .github/workflows/main.yml | 67 ++++++++++++++++--- Readme.md | 10 +++ YoutubeDownloader/.gitignore | 2 +- YoutubeDownloader/DownloadFFmpeg.ps1 | 29 ++++---- YoutubeDownloader/Services/UpdateService.cs | 11 ++- .../Components/DownloadViewModel.cs | 5 +- .../Views/Components/DashboardView.axaml | 2 + .../Views/Dialogs/SettingsView.axaml | 6 +- YoutubeDownloader/YoutubeDownloader.csproj | 24 +++++-- 9 files changed, 122 insertions(+), 34 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 85bac6110..f7a0f360b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,6 +40,17 @@ jobs: --configuration Release pack: + strategy: + matrix: + rid: + - win-arm64 + - win-x86 + - win-x64 + - linux-x64 + - osx-arm64 + - osx-x64 + + # Need to run on Windows because of DotnetRuntimeBootstrapper's dependency on Ressy runs-on: windows-latest timeout-minutes: 10 @@ -63,16 +74,17 @@ jobs: -p:CSharpier_Bypass=true --output YoutubeDownloader/bin/publish --configuration Release - --use-current-runtime + --runtime ${{ matrix.rid }} + --no-self-contained - name: Upload artifacts uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 with: - name: YoutubeDownloader + name: YoutubeDownloader.${{ matrix.rid }} path: YoutubeDownloader/bin/publish if-no-files-found: error - deploy: + release: if: ${{ github.ref_type == 'tag' }} needs: @@ -82,6 +94,36 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 + permissions: + contents: write + + steps: + - name: Create release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: > + gh release create ${{ github.ref_name }} + --repo ${{ github.event.repository.full_name }} + --title ${{ github.ref_name }} + --generate-notes + --verify-tag + + deploy: + needs: release + + strategy: + matrix: + rid: + - win-arm64 + - win-x86 + - win-x64 + - linux-x64 + - osx-arm64 + - osx-x64 + + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: actions: read contents: write @@ -90,24 +132,27 @@ jobs: - name: Download artifacts uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: - name: YoutubeDownloader + name: YoutubeDownloader.${{ matrix.rid }} path: YoutubeDownloader/ + - name: Set permissions + if: ${{ !startsWith(matrix.rid, 'win') }} + run: | + chmod +x YoutubeDownloader/YoutubeDownloader + chmod +x YoutubeDownloader/ffmpeg + - name: Create package # Change into the artifacts directory to avoid including the directory itself in the zip archive working-directory: YoutubeDownloader/ - run: zip -r ../YoutubeDownloader.zip . + run: zip -r ../YoutubeDownloader.${{ matrix.rid }}.zip . - - name: Create release + - name: Upload release asset env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: > - gh release create ${{ github.ref_name }} - YoutubeDownloader.zip + gh release upload ${{ github.ref_name }} + YoutubeDownloader.${{ matrix.rid }}.zip --repo ${{ github.event.repository.full_name }} - --title ${{ github.ref_name }} - --generate-notes - --verify-tag notify: needs: deploy diff --git a/Readme.md b/Readme.md index 7e998f332..a8a754daf 100644 --- a/Readme.md +++ b/Readme.md @@ -42,8 +42,18 @@ To learn more about the war and how you can help, [click here](https://tyrrrz.me - 🟢 **[Stable release](https://github.com/Tyrrrz/YoutubeDownloader/releases/latest)** - 🟠 [CI build](https://github.com/Tyrrrz/YoutubeDownloader/actions/workflows/main.yml) +> **Important**: +> To run **YoutubeDownloader**, you need to make sure that the **.NET 8.0 Runtime** is installed. +> You can download it here: +> +> - [.NET 8.0 Runtime for **macOS x64**](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-8.0.0-macos-x64-installer) +> - [.NET 8.0 Runtime for **macOS arm64**](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-8.0.0-macos-arm64-installer) +> - [.NET 8.0 Runtime for **Linux**](https://learn.microsoft.com/dotnet/core/install/linux) (find the correct download for your distro) +> - On **Windows**, the runtime should be installed automatically when you run the application for the first time + ## Features +- Fully cross-platform graphical user interface - Download videos by URL - Download videos from playlists or channels - Download videos by search query diff --git a/YoutubeDownloader/.gitignore b/YoutubeDownloader/.gitignore index dbabf19a3..97886974a 100644 --- a/YoutubeDownloader/.gitignore +++ b/YoutubeDownloader/.gitignore @@ -1 +1 @@ -/ffmpeg.exe \ No newline at end of file +/ffmpeg* \ No newline at end of file diff --git a/YoutubeDownloader/DownloadFFmpeg.ps1 b/YoutubeDownloader/DownloadFFmpeg.ps1 index e069702e0..84d97390e 100644 --- a/YoutubeDownloader/DownloadFFmpeg.ps1 +++ b/YoutubeDownloader/DownloadFFmpeg.ps1 @@ -1,35 +1,36 @@ +param ( + [string]$platform, + [string]$outputPath +) + $ErrorActionPreference = "Stop" -$ffmpegFilePath = "$PSScriptRoot/ffmpeg.exe" + +# Normalize platform identifier +$platform = $platform.ToLower().Replace("win-", "windows-") # Check if already exists -if (Test-Path $ffmpegFilePath) { +if (Test-Path $outputPath) { Write-Host "Skipped downloading FFmpeg, file already exists." exit } -Write-Host "Downloading FFmpeg..." - # Download the archive +Write-Host "Downloading FFmpeg..." [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $http = New-Object System.Net.WebClient try { - $http.DownloadFile("https://github.com/Tyrrrz/FFmpegBin/releases/download/6.1/ffmpeg-windows-x64.zip", "$ffmpegFilePath.zip") + $http.DownloadFile("https://github.com/Tyrrrz/FFmpegBin/releases/download/6.1.1/ffmpeg-$platform.zip", "$outputPath.zip") } finally { $http.Dispose() } try { - Import-Module "$PSHOME/Modules/Microsoft.PowerShell.Utility" -Function Get-FileHash - $hashResult = Get-FileHash "$ffmpegFilePath.zip" -Algorithm SHA256 - if ($hashResult.Hash -ne "48130a80aebffb61d06913350c3ad3187efd85096f898045fd65001bf89d7d7f") { - throw "Failed to verify the hash of the FFmpeg archive." - } - # Extract FFmpeg Add-Type -Assembly System.IO.Compression.FileSystem - $zip = [IO.Compression.ZipFile]::OpenRead("$ffmpegFilePath.zip") + $zip = [IO.Compression.ZipFile]::OpenRead("$outputPath.zip") try { - [IO.Compression.ZipFileExtensions]::ExtractToFile($zip.GetEntry("ffmpeg.exe"), $ffmpegFilePath) + $fileName = If ($platform.Contains("windows-")) { "ffmpeg.exe" } Else { "ffmpeg" } + [IO.Compression.ZipFileExtensions]::ExtractToFile($zip.GetEntry($fileName), $outputPath) } finally { $zip.Dispose() } @@ -37,5 +38,5 @@ try { Write-Host "Done downloading FFmpeg." } finally { # Clean up - Remove-Item "$ffmpegFilePath.zip" -Force + Remove-Item "$outputPath.zip" -Force } \ No newline at end of file diff --git a/YoutubeDownloader/Services/UpdateService.cs b/YoutubeDownloader/Services/UpdateService.cs index 3bc580c3f..cabb95e52 100644 --- a/YoutubeDownloader/Services/UpdateService.cs +++ b/YoutubeDownloader/Services/UpdateService.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Onova; using Onova.Exceptions; @@ -9,7 +10,15 @@ namespace YoutubeDownloader.Services; public class UpdateService(SettingsService settingsService) : IDisposable { private readonly IUpdateManager _updateManager = new UpdateManager( - new GithubPackageResolver("Tyrrrz", "YoutubeDownloader", "YoutubeDownloader.zip"), + new GithubPackageResolver( + "Tyrrrz", + "YoutubeDownloader", + // Examples: + // YoutubeDownloader.win-arm64.zip + // YoutubeDownloader.win-x64.zip + // YoutubeDownloader.linux-x64.zip + $"YoutubeDownloader.{RuntimeInformation.RuntimeIdentifier}.zip" + ), new ZipPackageExtractor() ); diff --git a/YoutubeDownloader/ViewModels/Components/DownloadViewModel.cs b/YoutubeDownloader/ViewModels/Components/DownloadViewModel.cs index ecb6b3094..e44c6da36 100644 --- a/YoutubeDownloader/ViewModels/Components/DownloadViewModel.cs +++ b/YoutubeDownloader/ViewModels/Components/DownloadViewModel.cs @@ -82,7 +82,10 @@ private void Cancel() _cancellationTokenSource.Cancel(); } - private bool CanShowFile() => Status == DownloadStatus.Completed; + private bool CanShowFile() => + Status == DownloadStatus.Completed + // This only works on Windows currently + && OperatingSystem.IsWindows(); [RelayCommand(CanExecute = nameof(CanShowFile))] private async Task ShowFileAsync() diff --git a/YoutubeDownloader/Views/Components/DashboardView.axaml b/YoutubeDownloader/Views/Components/DashboardView.axaml index ba704b249..2a75547d0 100644 --- a/YoutubeDownloader/Views/Components/DashboardView.axaml +++ b/YoutubeDownloader/Views/Components/DashboardView.axaml @@ -64,6 +64,8 @@ VerticalAlignment="Center" Command="{Binding ShowAuthSetupCommand}" Foreground="{DynamicResource MaterialDarkForegroundBrush}" + IsVisible="{OnPlatform False, + Windows=True}" Theme="{DynamicResource MaterialFlatButton}" ToolTip.Tip="Authentication"> - + - + + + $(RuntimeIdentifier) + win-arm64 + win-x86 + win-x64 + linux-arm64 + linux-x86 + linux-x64 + osx-arm64 + osx-x64 + ffmpeg.exe + ffmpeg + + - - + + - - + + \ No newline at end of file