name: Build Windows 64-bit on: workflow_dispatch: push: paths: - "juc500_xfer/**" - "juc500_app.py" - "juc500-windows.spec" - "juc500-windows-onefile.spec" - "build-installer-windows.bat" - "build-installer-windows.sh" - "packaging/windows/**" - "vendor/libusb-1.0.dll" - "requirements.txt" - ".github/workflows/build-windows.yml" jobs: windows: runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Verify libusb DLL shell: pwsh run: | if (-not (Test-Path "vendor\libusb-1.0.dll")) { throw "vendor/libusb-1.0.dll missing — commit the Windows x64 DLL" } - name: Build with PyInstaller shell: cmd run: | python -m pip install -U pip pyinstaller pyusb python -m PyInstaller --noconfirm --clean juc500-windows.spec if not exist dist\JUC500\JUC500.exe exit /b 1 if not exist dist\JUC500\_internal\static\index.html ( if not exist dist\JUC500\_internal\juc500_xfer\static\index.html ( echo ERROR: static index.html missing dir /s /b dist\JUC500\_internal 2>nul exit /b 1 ) ) python -m PyInstaller --noconfirm --clean juc500-windows-onefile.spec if not exist dist\JUC500-portable.exe exit /b 1 copy /Y packaging\windows\install.ps1 dist\JUC500\install.ps1 copy /Y packaging\windows\setup.bat dist\JUC500\setup.bat copy /Y packaging\windows\README-WIN.txt dist\JUC500\README-WIN.txt copy /Y packaging\windows\zadig-hint.url dist\JUC500\zadig-hint.url copy /Y vendor\libusb-1.0.dll dist\JUC500\libusb-1.0.dll - name: Smoke help shell: pwsh run: | $env:PYTHONUTF8 = "1" $p = Start-Process -FilePath "dist\JUC500\JUC500.exe" -ArgumentList "info" -PassThru -Wait -NoNewWindow ` -RedirectStandardOutput "smoke-out.txt" -RedirectStandardError "smoke-err.txt" Write-Host "--- stdout ---"; Get-Content smoke-out.txt -ErrorAction SilentlyContinue Write-Host "--- stderr ---"; Get-Content smoke-err.txt -ErrorAction SilentlyContinue $err = ((Get-Content smoke-err.txt -Raw -ErrorAction SilentlyContinue) + (Get-Content smoke-out.txt -Raw -ErrorAction SilentlyContinue)) if ($err -match "No module named") { throw "import failed: $err" } Write-Host "smoke ok exit=$($p.ExitCode)" - name: Zip portable shell: pwsh run: | New-Item -ItemType Directory -Force -Path dist-windows | Out-Null Compress-Archive -Path dist\JUC500\* -DestinationPath dist-windows\JUC500-win64-portable.zip -Force Copy-Item dist\JUC500-portable.exe dist-windows\JUC500-portable.exe -Force Copy-Item packaging\windows\README-WIN.txt dist-windows\README-WIN.txt -Force Copy-Item packaging\windows\install.ps1 dist-windows\install.ps1 -Force - name: Install Inno Setup and build Setup.exe shell: pwsh run: | choco install innosetup -y --no-progress & "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" packaging\windows\juc500.iss if (-not (Test-Path "dist-windows\JUC500-Setup-win64.exe")) { throw "Setup.exe was not created" } - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: juc500-windows-x64 path: | dist-windows/JUC500-Setup-win64.exe dist-windows/JUC500-win64-portable.zip dist-windows/JUC500-portable.exe if-no-files-found: error