From 101a55552e989219bf21d59cb473d00c29b70f04 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:39:00 +0100 Subject: [PATCH] feat: woa support --- .github/workflows/build.yml | 97 ++++++++++++++++++--- windows/CMakeLists.txt | 56 +++++++++--- windows/build-installer.ps1 | 169 +++++++++++++++++++++++++++++------- 3 files changed, 269 insertions(+), 53 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b2edb438..aa9ccc25 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,11 +280,9 @@ jobs: name: macos-dmg path: plezy-macos.dmg - build-windows: + build-windows-x64: runs-on: windows-latest permissions: - id-token: write - attestations: write contents: read steps: - uses: actions/checkout@v4 @@ -307,26 +305,98 @@ jobs: - name: Install dependencies run: flutter pub get - - name: Build Windows + - name: Build Windows x64 run: flutter build windows --release --dart-define=ENABLE_UPDATE_CHECK=true - - name: Build Windows Installer - run: .\windows\build-installer.ps1 + - name: Upload x64 build + uses: actions/upload-artifact@v4 + with: + name: windows-x64-build + path: build/windows/x64/runner/Release/ + + build-windows-arm64: + runs-on: windows-11-arm + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Install 7-Zip + run: choco install 7zip -y + + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + channel: "master" + cache: true + + - name: Cache Pub dependencies + uses: actions/cache@v4 + with: + path: | + ~\AppData\Local\Pub\Cache + key: ${{ runner.os }}-arm64-pub-${{ hashFiles('**/pubspec.lock') }} + restore-keys: | + ${{ runner.os }}-arm64-pub- + + - name: Install dependencies + run: flutter pub get + + - name: Build Windows arm64 + run: flutter build windows --release --dart-define=ENABLE_UPDATE_CHECK=true + + - name: Upload arm64 build + uses: actions/upload-artifact@v4 + with: + name: windows-arm64-build + path: build/windows/arm64/runner/Release/ + + package-windows: + needs: [build-windows-x64, build-windows-arm64] + runs-on: windows-latest + permissions: + id-token: write + attestations: write + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Download x64 build + uses: actions/download-artifact@v4 + with: + name: windows-x64-build + path: build-x64 + + - name: Download arm64 build + uses: actions/download-artifact@v4 + with: + name: windows-arm64-build + path: build-arm64 + + - name: Build installer and portables + run: .\windows\build-installer.ps1 -X64BuildDir "build-x64" -Arm64BuildDir "build-arm64" - name: Attest Windows artifacts uses: actions/attest-build-provenance@v2 with: subject-path: | - plezy-windows-portable.7z + plezy-windows-x64-portable.7z + plezy-windows-arm64-portable.7z plezy-windows-installer.exe - - name: Upload Portable Archive + - name: Upload x64 portable uses: actions/upload-artifact@v4 with: - name: windows-portable - path: plezy-windows-portable.7z + name: windows-x64-portable + path: plezy-windows-x64-portable.7z - - name: Upload Installer + - name: Upload arm64 portable + uses: actions/upload-artifact@v4 + with: + name: windows-arm64-portable + path: plezy-windows-arm64-portable.7z + + - name: Upload installer uses: actions/upload-artifact@v4 with: name: windows-installer @@ -409,7 +479,7 @@ jobs: plezy-linux.pkg.tar.zst create-release: - needs: [build-android, build-ios, build-macos, build-windows, build-linux] + needs: [build-android, build-ios, build-macos, package-windows, build-linux] runs-on: ubuntu-latest permissions: contents: write @@ -431,7 +501,8 @@ jobs: artifacts/android-apk/plezy-android-x86_64.tar.gz artifacts/ios-ipa/plezy-ios.ipa artifacts/macos-dmg/plezy-macos.dmg - artifacts/windows-portable/plezy-windows-portable.7z + artifacts/windows-x64-portable/plezy-windows-x64-portable.7z + artifacts/windows-arm64-portable/plezy-windows-arm64-portable.7z artifacts/windows-installer/plezy-windows-installer.exe artifacts/linux-app/plezy-linux.tar.gz artifacts/linux-packages/* diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index b9e3d023..52f426b9 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -2,17 +2,53 @@ cmake_minimum_required(VERSION 3.14) project(plezy LANGUAGES CXX) -# Download and extract mpv-dev -include(FetchContent) -FetchContent_Declare( - mpv_dev - URL https://github.com/shinchiro/mpv-winbuild-cmake/releases/download/20260120/mpv-dev-x86_64-v3-20260120-git-b7e8fe9.7z - DOWNLOAD_EXTRACT_TIMESTAMP TRUE -) -FetchContent_MakeAvailable(mpv_dev) +# Download and extract mpv-dev (architecture-dependent) +set(MPV_VERSION "20260120") +set(MPV_GIT_HASH "b7e8fe9") -set(MPV_INCLUDE_DIR "${mpv_dev_SOURCE_DIR}/include") -set(MPV_LIB_DIR "${mpv_dev_SOURCE_DIR}") +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + # ARM64: use file(DOWNLOAD) + 7z extraction (CMake's built-in libarchive + # can't handle LZMA2 on ARM64) + set(MPV_FILENAME "mpv-dev-aarch64-${MPV_VERSION}-git-${MPV_GIT_HASH}.7z") + set(MPV_URL "https://github.com/shinchiro/mpv-winbuild-cmake/releases/download/${MPV_VERSION}/${MPV_FILENAME}") + set(MPV_DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/mpv-dev-arm64") + set(MPV_ARCHIVE "${MPV_DOWNLOAD_DIR}/${MPV_FILENAME}") + + if(NOT EXISTS "${MPV_DOWNLOAD_DIR}/libmpv-2.dll") + message(STATUS "Downloading MPV for ARM64...") + file(DOWNLOAD "${MPV_URL}" "${MPV_ARCHIVE}" SHOW_PROGRESS STATUS MPV_DL_STATUS) + list(GET MPV_DL_STATUS 0 MPV_DL_RESULT) + if(NOT MPV_DL_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to download MPV: ${MPV_DL_STATUS}") + endif() + + find_program(7Z_EXECUTABLE 7z REQUIRED HINTS "C:/Program Files/7-Zip") + message(STATUS "Extracting MPV with ${7Z_EXECUTABLE}...") + execute_process( + COMMAND "${7Z_EXECUTABLE}" x "${MPV_ARCHIVE}" "-o${MPV_DOWNLOAD_DIR}" -y + RESULT_VARIABLE MPV_EXTRACT_RESULT + ) + if(NOT MPV_EXTRACT_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to extract MPV archive") + endif() + file(REMOVE "${MPV_ARCHIVE}") + endif() + + set(MPV_INCLUDE_DIR "${MPV_DOWNLOAD_DIR}/include") + set(MPV_LIB_DIR "${MPV_DOWNLOAD_DIR}") +else() + # x64 (AMD64): use FetchContent (existing behavior) + include(FetchContent) + FetchContent_Declare( + mpv_dev + URL https://github.com/shinchiro/mpv-winbuild-cmake/releases/download/${MPV_VERSION}/mpv-dev-x86_64-v3-${MPV_VERSION}-git-${MPV_GIT_HASH}.7z + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + FetchContent_MakeAvailable(mpv_dev) + + set(MPV_INCLUDE_DIR "${mpv_dev_SOURCE_DIR}/include") + set(MPV_LIB_DIR "${mpv_dev_SOURCE_DIR}") +endif() # The name of the executable created for the application. Change this to change # the on-disk name of your application. diff --git a/windows/build-installer.ps1 b/windows/build-installer.ps1 index ae3b23ca..0c141c9d 100644 --- a/windows/build-installer.ps1 +++ b/windows/build-installer.ps1 @@ -1,10 +1,13 @@ #!/usr/bin/env pwsh # Windows Installer Build Script -# This script creates both a portable archive and an installer for the Windows build +# Creates per-arch portable archives and a unified installer that auto-detects architecture. +# Supports single-arch (backward compat) and dual-arch builds. param( [string]$OutputDir = ".", - [string]$Version = "1.0.0" + [string]$Version = "1.0.0", + [string]$X64BuildDir, + [string]$Arm64BuildDir ) $ErrorActionPreference = "Stop" @@ -16,19 +19,27 @@ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $ProjectRoot = Split-Path -Parent $ScriptDir Set-Location $ProjectRoot -# Define paths -$BuildDir = "build\windows\x64\runner\Release" -$PortableZip = Join-Path (Resolve-Path $OutputDir) "plezy-windows-portable.7z" -$InstallerExe = Join-Path (Resolve-Path $OutputDir) "plezy-windows-installer.exe" -$SetupScript = "setup.iss" +$ResolvedOutput = Resolve-Path $OutputDir -# Check if build exists -if (-not (Test-Path $BuildDir)) { - Write-Error "Build directory not found at $BuildDir. Please run 'flutter build windows --release' first." +# Auto-detect build dirs from default Flutter output paths if not provided +if (-not $X64BuildDir -and (Test-Path "build\windows\x64\runner\Release")) { + $X64BuildDir = "build\windows\x64\runner\Release" +} +if (-not $Arm64BuildDir -and (Test-Path "build\windows\arm64\runner\Release")) { + $Arm64BuildDir = "build\windows\arm64\runner\Release" +} + +$HasX64 = $X64BuildDir -and (Test-Path $X64BuildDir) +$HasArm64 = $Arm64BuildDir -and (Test-Path $Arm64BuildDir) + +if (-not $HasX64 -and -not $HasArm64) { + Write-Error "No build directories found. Provide -X64BuildDir and/or -Arm64BuildDir, or run 'flutter build windows --release' first." exit 1 } -Write-Host "Found build at: $BuildDir" -ForegroundColor Green +Write-Host "Architectures found:" -ForegroundColor Green +if ($HasX64) { Write-Host " x64: $X64BuildDir" } +if ($HasArm64) { Write-Host " arm64: $Arm64BuildDir" } # Check for 7-Zip Write-Host "`nChecking for 7-Zip..." -ForegroundColor Cyan @@ -49,22 +60,57 @@ if (-not (Get-Command 7z -ErrorAction SilentlyContinue)) { } } -# Create Portable Archive -Write-Host "`nCreating portable archive..." -ForegroundColor Cyan -Push-Location $BuildDir -try { - if (Test-Path $PortableZip) { - Remove-Item $PortableZip -Force +# Create Portable Archives +if ($HasX64) { + Write-Host "`nCreating x64 portable archive..." -ForegroundColor Cyan + $X64Portable = Join-Path $ResolvedOutput "plezy-windows-x64-portable.7z" + Push-Location $X64BuildDir + try { + if (Test-Path $X64Portable) { Remove-Item $X64Portable -Force } + 7z a -mx=9 $X64Portable * + Write-Host "Created: $X64Portable" -ForegroundColor Green + } finally { + Pop-Location } - 7z a -mx=9 $PortableZip * - Write-Host "Created: $PortableZip" -ForegroundColor Green -} finally { - Pop-Location } -# Create Inno Setup Script +if ($HasArm64) { + Write-Host "`nCreating arm64 portable archive..." -ForegroundColor Cyan + $Arm64Portable = Join-Path $ResolvedOutput "plezy-windows-arm64-portable.7z" + Push-Location $Arm64BuildDir + try { + if (Test-Path $Arm64Portable) { Remove-Item $Arm64Portable -Force } + 7z a -mx=9 $Arm64Portable * + Write-Host "Created: $Arm64Portable" -ForegroundColor Green + } finally { + Pop-Location + } +} + +# Stage files for Inno Setup +Write-Host "`nStaging files for installer..." -ForegroundColor Cyan +$StagingDir = "staging" +if (Test-Path $StagingDir) { Remove-Item $StagingDir -Recurse -Force } + +if ($HasX64) { + $X64Staging = Join-Path $StagingDir "x64" + New-Item -ItemType Directory -Path $X64Staging -Force | Out-Null + Copy-Item -Path "$X64BuildDir\*" -Destination $X64Staging -Recurse +} +if ($HasArm64) { + $Arm64Staging = Join-Path $StagingDir "arm64" + New-Item -ItemType Directory -Path $Arm64Staging -Force | Out-Null + Copy-Item -Path "$Arm64BuildDir\*" -Destination $Arm64Staging -Recurse +} + +# Generate Inno Setup Script Write-Host "`nGenerating Inno Setup script..." -ForegroundColor Cyan -@" +$SetupScript = "setup.iss" +$DualArch = $HasX64 -and $HasArm64 + +if ($DualArch) { + # Dual-arch unified installer with architecture detection + $IssContent = @" #define Name "Plezy" #define Version "$Version" #define Publisher "edde746" @@ -84,8 +130,8 @@ Compression=lzma SolidCompression=yes WizardStyle=modern PrivilegesRequired=lowest -ArchitecturesAllowed=x64 -ArchitecturesInstallIn64BitMode=x64 +ArchitecturesAllowed=x64compatible arm64 +ArchitecturesInstallIn64BitMode=x64compatible arm64 [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" @@ -94,7 +140,8 @@ Name: "english"; MessagesFile: "compiler:Default.isl" Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] -Source: "build\windows\x64\runner\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "staging\x64\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: IsX64 +Source: "staging\arm64\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs solidbreak; Check: IsArm64 [Icons] Name: "{group}\{#Name}"; Filename: "{app}\{#ExeName}" @@ -103,8 +150,66 @@ Name: "{autodesktop}\{#Name}"; Filename: "{app}\{#ExeName}"; Tasks: desktopicon [Run] Filename: "{app}\{#ExeName}"; Description: "{cm:LaunchProgram,{#Name}}"; Flags: nowait postinstall skipifsilent -"@ | Out-File -FilePath $SetupScript -Encoding ASCII +[Code] +function IsX64: Boolean; +begin + Result := not IsArm64; +end; +"@ +} else { + # Single-arch installer (backward compatible, no Check: functions needed) + if ($HasX64) { + $ArchAllowed = "x64compatible" + $StagingSource = "staging\x64\*" + } else { + $ArchAllowed = "arm64" + $StagingSource = "staging\arm64\*" + } + + $IssContent = @" +#define Name "Plezy" +#define Version "$Version" +#define Publisher "edde746" +#define ExeName "plezy.exe" + +[Setup] +AppId={{4213385e-f7be-4f2b-95f9-54082a28bb8f} +AppName={#Name} +AppVersion={#Version} +AppPublisher={#Publisher} +DefaultDirName={autopf}\{#Name} +DefaultGroupName={#Name} +AllowNoIcons=yes +OutputDir=. +OutputBaseFilename=plezy-windows-installer +Compression=lzma +SolidCompression=yes +WizardStyle=modern +PrivilegesRequired=lowest +ArchitecturesAllowed=$ArchAllowed +ArchitecturesInstallIn64BitMode=$ArchAllowed + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "$StagingSource"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs + +[Icons] +Name: "{group}\{#Name}"; Filename: "{app}\{#ExeName}" +Name: "{group}\{cm:UninstallProgram,{#Name}}"; Filename: "{uninstallexe}" +Name: "{autodesktop}\{#Name}"; Filename: "{app}\{#ExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#ExeName}"; Description: "{cm:LaunchProgram,{#Name}}"; Flags: nowait postinstall skipifsilent +"@ +} + +$IssContent | Out-File -FilePath $SetupScript -Encoding ASCII Write-Host "Created: $SetupScript" -ForegroundColor Green # Check for Inno Setup @@ -114,7 +219,6 @@ $InnoSetupPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" if (-not (Test-Path $InnoSetupPath)) { Write-Host "Inno Setup not found. Installing via Chocolatey..." -ForegroundColor Yellow - # Check if choco is available if (-not (Get-Command choco -ErrorAction SilentlyContinue)) { Write-Error "Chocolatey is not installed. Please install it from https://chocolatey.org/install" exit 1 @@ -137,6 +241,11 @@ if ($LASTEXITCODE -ne 0) { exit 1 } +# Clean up staging +Remove-Item $StagingDir -Recurse -Force -ErrorAction SilentlyContinue + +# Summary Write-Host "`nBuild complete!" -ForegroundColor Green -Write-Host "Portable archive: $PortableZip" -ForegroundColor White -Write-Host "Installer: $InstallerExe" -ForegroundColor White +if ($HasX64) { Write-Host "Portable (x64): $X64Portable" -ForegroundColor White } +if ($HasArm64) { Write-Host "Portable (arm64): $Arm64Portable" -ForegroundColor White } +Write-Host "Installer: $(Join-Path $ResolvedOutput 'plezy-windows-installer.exe')" -ForegroundColor White