Switch Windows build to Python script, remove PowerShell
Replaces PowerShell build script with Python in CI workflow and deletes the old build/README.md and windows-build-universal.ps1. This streamlines the build process and consolidates build logic into Python for better maintainability.
This commit is contained in:
@@ -75,14 +75,14 @@ jobs:
|
||||
run: |
|
||||
.\venv\Scripts\Activate.ps1
|
||||
Write-Host "Building Standard Version..."
|
||||
.\build\windows\windows-build-universal.ps1 -Verbose
|
||||
python build\windows\windows_build_universal.py --verbose
|
||||
|
||||
- name: Build FFmpeg Version (MSI + ZIP)
|
||||
shell: powershell
|
||||
run: |
|
||||
.\venv\Scripts\Activate.ps1
|
||||
Write-Host "Building FFmpeg Version..."
|
||||
.\build\windows\windows-build-universal.ps1 -FFmpeg -Verbose
|
||||
python build\windows\windows_build_universal.py --ffmpeg --verbose
|
||||
|
||||
- name: Prepare release artifacts
|
||||
shell: powershell
|
||||
|
||||
-211
@@ -1,211 +0,0 @@
|
||||
# YTSage Build System
|
||||
|
||||
This directory contains all build-related files and configurations for creating YTSage distributions.
|
||||
|
||||
## 🏗️ Build Architecture
|
||||
|
||||
### Automated Builds (CI/CD)
|
||||
- **GitHub Actions**: Fully automated releases triggered by git tags
|
||||
- **Location**: `.github/workflows/build-windows.yml`
|
||||
- **Triggers**: Version tags (e.g., `v4.8.0`, `v4.9.1`)
|
||||
- **Output**: MSI installers + ZIP portable versions (Standard & FFmpeg)
|
||||
|
||||
### Local Development Builds
|
||||
- **Script**: `build/windows/windows-build-universal.ps1`
|
||||
- **Purpose**: Local testing and development
|
||||
- **Flexibility**: Manual control over build options
|
||||
|
||||
## 📁 Directory Structure
|
||||
|
||||
```
|
||||
build/
|
||||
├── windows/
|
||||
│ ├── setup.py # Standard cx_Freeze configuration
|
||||
│ ├── setup-ffmpeg.py # FFmpeg bundle cx_Freeze configuration
|
||||
│ ├── windows-build-universal.ps1 # Local development build script
|
||||
│ └── README.md # This file
|
||||
└── (future platforms)
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### For Releases (Recommended)
|
||||
```bash
|
||||
# Create and push a version tag
|
||||
git tag v4.8.1
|
||||
git push origin v4.8.1
|
||||
|
||||
# GitHub Actions will automatically:
|
||||
# 1. Build both versions
|
||||
# 2. Create MSI installers
|
||||
# 3. Create ZIP portable versions
|
||||
# 4. Generate draft release with artifacts
|
||||
```
|
||||
|
||||
### For Local Development
|
||||
```powershell
|
||||
# Navigate to project root
|
||||
cd c:\path\to\YTSage\build-env
|
||||
|
||||
# Run the universal build script
|
||||
.\build\windows\windows-build-universal.ps1 -Verbose
|
||||
|
||||
# Build only FFmpeg version
|
||||
.\build\windows\windows-build-universal.ps1 -FFmpeg -Verbose
|
||||
|
||||
# Build only MSI (no ZIP)
|
||||
.\build\windows\windows-build-universal.ps1 -MSIOnly
|
||||
|
||||
# Build only ZIP (no MSI)
|
||||
.\build\windows\windows-build-universal.ps1 -ZIPOnly
|
||||
```
|
||||
|
||||
## 📋 Build Configurations
|
||||
|
||||
### Standard Version (`setup.py`)
|
||||
- **Target**: General users
|
||||
- **Size**: Smaller download
|
||||
- **FFmpeg**: Downloaded automatically when needed
|
||||
|
||||
### FFmpeg Bundle (`setup-ffmpeg.py`)
|
||||
- **Target**: Users without internet or restricted environments
|
||||
- **Size**: Larger download (~100MB+)
|
||||
- **FFmpeg**: Included in installer
|
||||
|
||||
## 🔧 Build Script Options
|
||||
|
||||
### windows-build-universal.ps1 Parameters
|
||||
```powershell
|
||||
-SkipVenv # Skip virtual environment creation
|
||||
-Verbose # Enable detailed output
|
||||
-FFmpeg # Build FFmpeg bundle version
|
||||
-MSIOnly # Create only MSI installer
|
||||
-ZIPOnly # Create only ZIP distribution
|
||||
-OutputDir # Custom output directory (default: "releases")
|
||||
-FFmpegPath # Custom FFmpeg binaries path
|
||||
```
|
||||
|
||||
### Examples
|
||||
```powershell
|
||||
# Full build with verbose output
|
||||
.\build\windows\windows-build-universal.ps1 -Verbose
|
||||
|
||||
# Quick standard version build
|
||||
.\build\windows\windows-build-universal.ps1 -MSIOnly
|
||||
|
||||
# FFmpeg version to custom directory
|
||||
.\build\windows\windows-build-universal.ps1 -FFmpeg -OutputDir "custom-builds"
|
||||
```
|
||||
|
||||
## 📦 Output Artifacts
|
||||
|
||||
### CI/CD Builds (GitHub Actions)
|
||||
```
|
||||
releases/
|
||||
├── YTSage-v4.8.1.msi # Standard installer
|
||||
├── YTSage-v4.8.1.zip # Standard portable
|
||||
├── YTSage-v4.8.1-ffmpeg.msi # FFmpeg installer
|
||||
└── YTSage-v4.8.1-ffmpeg.zip # FFmpeg portable
|
||||
```
|
||||
|
||||
### Local Builds
|
||||
```
|
||||
releases/
|
||||
├── YTSage-4.8.1.msi # Standard installer
|
||||
├── YTSage-4.8.1.zip # Standard portable
|
||||
├── YTSage-4.8.1-ffmpeg.msi # FFmpeg installer (if built)
|
||||
└── YTSage-4.8.1-ffmpeg.zip # FFmpeg portable (if built)
|
||||
```
|
||||
|
||||
## 🛠️ Build Requirements
|
||||
|
||||
### System Requirements
|
||||
- **OS**: Windows 10/11
|
||||
- **PowerShell**: 5.1 or later
|
||||
- **Python**: 3.12+ (3.12.10 recommended for MSI compatibility)
|
||||
- **Memory**: 4GB+ RAM recommended
|
||||
- **Storage**: 2GB+ free space
|
||||
|
||||
### Python Dependencies
|
||||
- **cx_Freeze**: 6.x for MSI creation
|
||||
- **playsound3**: Audio notification system
|
||||
- **All project dependencies**: Listed in `requirements.txt`
|
||||
|
||||
### Optional Components
|
||||
- **FFmpeg**: For bundled builds (auto-downloaded if not present)
|
||||
- **Code Signing**: Certificate for signed installers (optional)
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Build Fails with Import Errors
|
||||
```powershell
|
||||
# Recreate virtual environment
|
||||
Remove-Item venv -Recurse -Force
|
||||
.\build\windows\windows-build-universal.ps1 -Verbose
|
||||
```
|
||||
|
||||
#### MSI Creation Fails
|
||||
- Ensure Python 3.12.x (required for MSI compatibility)
|
||||
- Check cx_Freeze version (should be 6.x)
|
||||
- Verify all dependencies are installed
|
||||
|
||||
#### FFmpeg Not Found
|
||||
```powershell
|
||||
# Specify custom FFmpeg path
|
||||
.\build\windows\windows-build-universal.ps1 -FFmpeg -FFmpegPath "C:\ffmpeg\bin"
|
||||
```
|
||||
|
||||
#### CI/CD Build Fails
|
||||
- Check GitHub Actions logs
|
||||
- Verify tag format (`v*`)
|
||||
- Ensure all required files are present
|
||||
- Check file paths in workflow
|
||||
|
||||
### Debug Mode
|
||||
```powershell
|
||||
# Enable maximum verbosity
|
||||
.\build\windows\windows-build-universal.ps1 -Verbose -Debug
|
||||
```
|
||||
|
||||
## 📈 Version Management
|
||||
|
||||
### Automatic Version Detection
|
||||
- **CI/CD**: Extracts version from git tag
|
||||
- **Local**: Uses version from setup.py files
|
||||
- **Format**: Semantic versioning (e.g., 4.8.1)
|
||||
|
||||
### Manual Version Update
|
||||
```powershell
|
||||
# Update version in setup files
|
||||
(Get-Content build\windows\setup.py) -replace 'version="[^"]*"', 'version="4.8.2"' | Set-Content build\windows\setup.py
|
||||
(Get-Content build\windows\setup-ffmpeg.py) -replace 'version="[^"]*"', 'version="4.8.2"' | Set-Content build\windows\setup-ffmpeg.py
|
||||
```
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
### Planned Features
|
||||
- **Linux builds**: Future cross-platform support
|
||||
- **macOS builds**: Apple platform support
|
||||
- **Auto-updater**: Built-in update mechanism
|
||||
- **Digital signing**: Code signing for Windows
|
||||
|
||||
### Contributing
|
||||
- Build improvements welcome
|
||||
- Cross-platform configurations
|
||||
- Performance optimizations
|
||||
- Documentation enhancements
|
||||
|
||||
## 📚 Related Documentation
|
||||
|
||||
- **CI/CD Guide**: `.github/CI_CD_README.md`
|
||||
- **Project README**: `../README.md`
|
||||
- **Release Notes**: GitHub Releases
|
||||
- **Issue Tracking**: GitHub Issues
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: August 2025
|
||||
**Build System Version**: 4.8.x
|
||||
**Supported Platforms**: Windows (primary)
|
||||
@@ -1,474 +0,0 @@
|
||||
#Requires -Version 5.1
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
YTSage Universal Build Script - Creates MSI Installers and ZIP Distributions
|
||||
.DESCRIPTION
|
||||
This PowerShell script builds YTSage using cx_Freeze and creates:
|
||||
- MSI installer packages
|
||||
- ZIP file distributions (portable)
|
||||
- Both standard and FFmpeg versions
|
||||
.NOTES
|
||||
Version: Auto-detected from setup.py
|
||||
Location: build/windows/windows-build-universal.ps1
|
||||
Usage: Run from project root directory (build-env/)
|
||||
|
||||
IMPORTANT: This script must be executed from the project root directory!
|
||||
Example: .\build\windows\windows-build-universal.ps1 -Verbose
|
||||
#>
|
||||
|
||||
param(
|
||||
[switch]$SkipVenv,
|
||||
[switch]$Verbose,
|
||||
[switch]$FFmpeg,
|
||||
[switch]$MSIOnly,
|
||||
[switch]$ZIPOnly,
|
||||
[string]$OutputDir = "releases",
|
||||
[string]$FFmpegPath = "$env:LOCALAPPDATA\ffmpeg\ffmpeg-7.1.1-full_build\bin"
|
||||
)
|
||||
|
||||
# Set error handling
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Script configuration - Auto-detect version from setup.py
|
||||
$APP_NAME = "YTSage"
|
||||
$RELEASE_DATE = Get-Date -Format "yyyy-MM-dd"
|
||||
|
||||
# Auto-detect version from setup.py
|
||||
function Get-VersionFromSetup {
|
||||
try {
|
||||
$setupContent = Get-Content "build\windows\setup.py" -Raw
|
||||
if ($setupContent -match 'version="([^"]*)"') {
|
||||
$version = $matches[1]
|
||||
Write-Host "Detected version: $version" -ForegroundColor Gray
|
||||
return $version
|
||||
} else {
|
||||
Write-Warning-Custom "Could not extract version from setup.py, using 1.0.0"
|
||||
return "1.0.0"
|
||||
}
|
||||
} catch {
|
||||
Write-Warning-Custom "Could not read setup.py, using 1.0.0"
|
||||
return "1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
$SCRIPT_VERSION = Get-VersionFromSetup
|
||||
|
||||
# Determine build type
|
||||
$BUILD_TYPE = if ($FFmpeg) { "FFmpeg" } else { "Standard" }
|
||||
$SETUP_FILE = if ($FFmpeg) { "build\windows\setup-ffmpeg.py" } else { "build\windows\setup.py" }
|
||||
$OUTPUT_NAME_BASE = if ($FFmpeg) { "$APP_NAME-v$SCRIPT_VERSION-ffmpeg" } else { "$APP_NAME-v$SCRIPT_VERSION" }
|
||||
|
||||
# Banner
|
||||
Write-Host "================================================" -ForegroundColor Cyan
|
||||
Write-Host "YTSage Universal Build Script v$SCRIPT_VERSION" -ForegroundColor Cyan
|
||||
Write-Host "Build Type: $BUILD_TYPE" -ForegroundColor Yellow
|
||||
Write-Host "================================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "This script will create:" -ForegroundColor Yellow
|
||||
if (-not $ZIPOnly) {
|
||||
Write-Host "- MSI installer package" -ForegroundColor White
|
||||
}
|
||||
if (-not $MSIOnly) {
|
||||
Write-Host "- ZIP portable distribution" -ForegroundColor White
|
||||
}
|
||||
Write-Host "- Professional packaging with metadata" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
function Write-Step {
|
||||
param($Message)
|
||||
Write-Host "[STEP] $Message" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Write-Error-Custom {
|
||||
param($Message)
|
||||
Write-Host "[ERROR] $Message" -ForegroundColor Red
|
||||
}
|
||||
|
||||
function Write-Warning-Custom {
|
||||
param($Message)
|
||||
Write-Host "[WARNING] $Message" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Test-Command {
|
||||
param($Command)
|
||||
try {
|
||||
& $Command --version | Out-Null
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Test-FFmpegBinaries {
|
||||
if (-not $FFmpeg) { return $null }
|
||||
|
||||
Write-Step "Checking FFmpeg binaries..."
|
||||
|
||||
$ffmpegExe = Join-Path $FFmpegPath "ffmpeg.exe"
|
||||
$ffprobeExe = Join-Path $FFmpegPath "ffprobe.exe"
|
||||
$ffplayExe = Join-Path $FFmpegPath "ffplay.exe"
|
||||
|
||||
$missingFiles = @()
|
||||
|
||||
if (-not (Test-Path $ffmpegExe)) { $missingFiles += "ffmpeg.exe" }
|
||||
if (-not (Test-Path $ffprobeExe)) { $missingFiles += "ffprobe.exe" }
|
||||
if (-not (Test-Path $ffplayExe)) { $missingFiles += "ffplay.exe" }
|
||||
|
||||
if ($missingFiles.Count -gt 0) {
|
||||
Write-Error-Custom "Missing FFmpeg binaries: $($missingFiles -join ', ')"
|
||||
Write-Host "Expected FFmpeg path: $FFmpegPath" -ForegroundColor Yellow
|
||||
throw "FFmpeg binaries not found"
|
||||
}
|
||||
|
||||
Write-Host "✓ Found all FFmpeg binaries" -ForegroundColor Green
|
||||
return @{
|
||||
ffmpeg = $ffmpegExe
|
||||
ffprobe = $ffprobeExe
|
||||
ffplay = $ffplayExe
|
||||
}
|
||||
}
|
||||
|
||||
function New-VirtualEnvironment {
|
||||
Write-Step "Creating virtual environment..."
|
||||
try {
|
||||
python -m venv venv
|
||||
Write-Host "Virtual environment created successfully." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to create virtual environment: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Start-VirtualEnvironment {
|
||||
Write-Step "Activating virtual environment..."
|
||||
|
||||
$venvScript = ".\venv\Scripts\Activate.ps1"
|
||||
if (-not (Test-Path $venvScript)) {
|
||||
Write-Error-Custom "Virtual environment activation script not found at: $venvScript"
|
||||
throw "Virtual environment not properly created"
|
||||
}
|
||||
|
||||
try {
|
||||
& $venvScript
|
||||
Write-Host "Virtual environment activated successfully." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to activate virtual environment: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Install-Dependencies {
|
||||
Write-Step "Installing/Upgrading required packages..."
|
||||
|
||||
try {
|
||||
Write-Host "Upgrading pip..." -ForegroundColor White
|
||||
python -m pip install --upgrade pip | Out-Null
|
||||
|
||||
Write-Host "Installing requirements..." -ForegroundColor White
|
||||
pip install --no-cache-dir -r requirements.txt | Out-Null
|
||||
|
||||
Write-Host "Installing cx_Freeze..." -ForegroundColor White
|
||||
pip install --no-cache-dir cx_Freeze | Out-Null
|
||||
|
||||
Write-Host "Installing yt-dlp (temporary for build)..." -ForegroundColor White
|
||||
pip install --no-cache-dir yt-dlp | Out-Null
|
||||
|
||||
Write-Host "All packages installed successfully." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to install required packages: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-BuildArtifacts {
|
||||
Write-Step "Cleaning previous build artifacts..."
|
||||
|
||||
$itemsToRemove = @("build", "dist", $OutputDir)
|
||||
|
||||
foreach ($item in $itemsToRemove) {
|
||||
if (Test-Path $item) {
|
||||
Remove-Item $item -Recurse -Force
|
||||
Write-Host "Removed: $item" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Build artifacts cleaned." -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Build-Executable {
|
||||
param($FFmpegBinaries)
|
||||
|
||||
Write-Step "Building executable with cx_Freeze..."
|
||||
|
||||
try {
|
||||
if ($FFmpegBinaries) {
|
||||
$env:FFMPEG_PATH = $FFmpegBinaries.ffmpeg | Split-Path
|
||||
}
|
||||
|
||||
# Build the executable
|
||||
python $SETUP_FILE build
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "cx_Freeze build failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host "Executable built successfully." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to build executable: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Build-MSI {
|
||||
Write-Step "Creating MSI installer..."
|
||||
|
||||
try {
|
||||
# Build MSI package
|
||||
python $SETUP_FILE bdist_msi
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "MSI build failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host "MSI installer created successfully." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to build MSI: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function New-ZIPDistribution {
|
||||
Write-Step "Creating ZIP distribution..."
|
||||
|
||||
try {
|
||||
# Ensure output directory exists
|
||||
if (-not (Test-Path $OutputDir)) {
|
||||
New-Item -ItemType Directory -Path $OutputDir | Out-Null
|
||||
}
|
||||
|
||||
# Find the built executable directory
|
||||
$executableDir = if ($FFmpeg) { "dist\YTSage-FFmpeg" } else { "dist\YTSage" }
|
||||
|
||||
if (-not (Test-Path $executableDir)) {
|
||||
throw "Executable directory not found: $executableDir"
|
||||
}
|
||||
|
||||
# Create ZIP file
|
||||
$zipPath = Join-Path $OutputDir "$OUTPUT_NAME_BASE.zip"
|
||||
Compress-Archive -Path "$executableDir\*" -DestinationPath $zipPath -Force
|
||||
|
||||
Write-Host "ZIP distribution created: $zipPath" -ForegroundColor Green
|
||||
|
||||
# Get ZIP file size
|
||||
$zipSize = (Get-Item $zipPath).Length
|
||||
$zipSizeMB = [math]::Round($zipSize / 1MB, 2)
|
||||
Write-Host "ZIP size: $zipSizeMB MB" -ForegroundColor Gray
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to create ZIP distribution: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Move-MSIFiles {
|
||||
Write-Step "Organizing MSI files..."
|
||||
|
||||
try {
|
||||
# Ensure output directory exists
|
||||
if (-not (Test-Path $OutputDir)) {
|
||||
New-Item -ItemType Directory -Path $OutputDir | Out-Null
|
||||
}
|
||||
|
||||
# Find and move MSI files
|
||||
$msiFiles = Get-ChildItem -Path "dist" -Filter "*.msi" -Recurse
|
||||
|
||||
foreach ($msiFile in $msiFiles) {
|
||||
$newName = "$OUTPUT_NAME_BASE.msi"
|
||||
$destination = Join-Path $OutputDir $newName
|
||||
|
||||
Move-Item $msiFile.FullName $destination -Force
|
||||
Write-Host "MSI installer moved to: $destination" -ForegroundColor Green
|
||||
|
||||
# Get MSI file size
|
||||
$msiSize = (Get-Item $destination).Length
|
||||
$msiSizeMB = [math]::Round($msiSize / 1MB, 2)
|
||||
Write-Host "MSI size: $msiSizeMB MB" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Failed to organize MSI files: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function New-ReleaseNotes {
|
||||
Write-Step "Creating release notes..."
|
||||
|
||||
$releaseNotes = "# YTSage v$SCRIPT_VERSION Release`n`n"
|
||||
$releaseNotes += "**Release Date:** $RELEASE_DATE`n"
|
||||
$releaseNotes += "**Build Type:** $BUILD_TYPE`n`n"
|
||||
$releaseNotes += "## Installation Options`n`n"
|
||||
$releaseNotes += "### MSI Installer (Recommended)`n"
|
||||
$releaseNotes += "- **File:** $OUTPUT_NAME_BASE.msi`n"
|
||||
$releaseNotes += "- **Installation:** Double-click to install system-wide`n"
|
||||
$releaseNotes += "- **Updates:** Automatic update notifications`n"
|
||||
$releaseNotes += "- **Uninstall:** Via Windows Programs `& Features`n`n"
|
||||
$releaseNotes += "### Portable ZIP`n"
|
||||
$releaseNotes += "- **File:** $OUTPUT_NAME_BASE.zip`n"
|
||||
$releaseNotes += "- **Installation:** Extract and run - no installation required`n"
|
||||
$releaseNotes += "- **Updates:** Manual download and replacement`n"
|
||||
$releaseNotes += "- **Uninstall:** Simply delete the folder`n`n"
|
||||
$releaseNotes += "## System Requirements`n"
|
||||
$releaseNotes += "- Windows 10/11 64-bit`n"
|
||||
$releaseNotes += "- .NET Framework 4.7.2 or later`n"
|
||||
$releaseNotes += "- Internet connection for yt-dlp updates`n`n"
|
||||
$releaseNotes += "## Support`n"
|
||||
$releaseNotes += "For issues or questions, please visit the project repository.`n`n"
|
||||
$releaseNotes += "---`n"
|
||||
$releaseNotes += "*Built with cx_Freeze*`n"
|
||||
|
||||
try {
|
||||
$releaseNotesPath = Join-Path $OutputDir "RELEASE_NOTES.md"
|
||||
$releaseNotes | Out-File -FilePath $releaseNotesPath -Encoding UTF8
|
||||
Write-Host "Release notes created: $releaseNotesPath" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning-Custom "Failed to create release notes: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-PostBuildArtifacts {
|
||||
Write-Step "Cleaning up post-build artifacts..."
|
||||
|
||||
try {
|
||||
if (Test-Path "build") {
|
||||
Remove-Item "build" -Recurse -Force
|
||||
Write-Host "Removed build folder." -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "Post-build cleanup completed." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning-Custom "Some cleanup operations failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Stop-VirtualEnvironment {
|
||||
try {
|
||||
deactivate
|
||||
Write-Host "Virtual environment deactivated." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning-Custom "Failed to deactivate virtual environment (this might be normal)"
|
||||
}
|
||||
}
|
||||
|
||||
function Show-BuildSummary {
|
||||
Write-Host ""
|
||||
Write-Host "================================================" -ForegroundColor Cyan
|
||||
Write-Host "Build completed successfully!" -ForegroundColor Green
|
||||
Write-Host "================================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Build Type: $BUILD_TYPE" -ForegroundColor Yellow
|
||||
Write-Host "Version: $SCRIPT_VERSION" -ForegroundColor Yellow
|
||||
Write-Host "Output Directory: $OutputDir" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
if (Test-Path $OutputDir) {
|
||||
Write-Host "Created files:" -ForegroundColor Green
|
||||
Get-ChildItem $OutputDir | ForEach-Object {
|
||||
$size = if ($_.PSIsContainer) { "Folder" } else { "$([math]::Round($_.Length / 1MB, 2)) MB" }
|
||||
Write-Host " ✓ $($_.Name) ($size)" -ForegroundColor White
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Distribution ready for release!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Main execution
|
||||
try {
|
||||
# Validation
|
||||
Write-Step "Checking prerequisites..."
|
||||
|
||||
if (-not (Test-Command "python")) {
|
||||
Write-Error-Custom "Python is not installed or not in PATH"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (-not (Test-Path $SETUP_FILE)) {
|
||||
Write-Error-Custom "Setup file not found: $SETUP_FILE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$pythonVersion = python --version
|
||||
Write-Host "Found: $pythonVersion" -ForegroundColor Green
|
||||
|
||||
# Check for Python 3.13 MSI limitation
|
||||
$pythonVersionInfo = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"
|
||||
$isPython313 = $pythonVersionInfo -eq "3.13"
|
||||
|
||||
if ($isPython313 -and -not $ZIPOnly) {
|
||||
Write-Warning-Custom "Python 3.13 detected. MSI building is not supported yet by cx_Freeze."
|
||||
Write-Host "See: https://github.com/marcelotduarte/cx_Freeze/issues/2837" -ForegroundColor Yellow
|
||||
Write-Host "Switching to ZIP-only mode. Use Python 3.12 for MSI support." -ForegroundColor Yellow
|
||||
$ZIPOnly = $true
|
||||
$MSIOnly = $false
|
||||
}
|
||||
|
||||
# Check FFmpeg if needed
|
||||
$ffmpegBinaries = Test-FFmpegBinaries
|
||||
|
||||
# Virtual environment
|
||||
if (-not $SkipVenv) {
|
||||
if (-not (Test-Path "venv")) {
|
||||
New-VirtualEnvironment
|
||||
} else {
|
||||
Write-Step "Using existing virtual environment..."
|
||||
}
|
||||
Start-VirtualEnvironment
|
||||
}
|
||||
|
||||
# Build process
|
||||
Install-Dependencies
|
||||
Remove-BuildArtifacts
|
||||
Build-Executable -FFmpegBinaries $ffmpegBinaries
|
||||
|
||||
# Create distributions
|
||||
if (-not $ZIPOnly) {
|
||||
Build-MSI
|
||||
Move-MSIFiles
|
||||
}
|
||||
|
||||
if (-not $MSIOnly) {
|
||||
New-ZIPDistribution
|
||||
}
|
||||
|
||||
New-ReleaseNotes
|
||||
Remove-PostBuildArtifacts
|
||||
Show-BuildSummary
|
||||
}
|
||||
catch {
|
||||
Write-Error-Custom "Build failed: $($_.Exception.Message)"
|
||||
if ($Verbose) {
|
||||
Write-Host $_.Exception.StackTrace -ForegroundColor Red
|
||||
}
|
||||
exit 1
|
||||
}
|
||||
finally {
|
||||
if (-not $SkipVenv) {
|
||||
Stop-VirtualEnvironment
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Press any key to continue..." -ForegroundColor Gray
|
||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
Reference in New Issue
Block a user