d435cac3d5
Replaces individual asset and source file mappings with broader 'src' and 'assets' directory includes in the cx_Freeze build steps. Also updates FFmpeg file inclusion to use only the source path, removing explicit destination mapping.
271 lines
11 KiB
YAML
271 lines
11 KiB
YAML
name: Build Windows Release
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*'
|
||
|
||
permissions:
|
||
contents: write
|
||
|
||
env:
|
||
PYTHON_VERSION: '3.12.10'
|
||
|
||
jobs:
|
||
build-windows:
|
||
runs-on: windows-latest
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: Extract version from tag
|
||
id: get_version
|
||
shell: powershell
|
||
run: |
|
||
$tag = "${{ github.ref_name }}"
|
||
$version = $tag -replace '^v', ''
|
||
Write-Host "Extracted version: $version"
|
||
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
|
||
|
||
- name: Setup Python
|
||
uses: actions/setup-python@v4
|
||
with:
|
||
python-version: ${{ env.PYTHON_VERSION }}
|
||
|
||
- name: Cache Python dependencies
|
||
uses: actions/cache@v3
|
||
with:
|
||
path: |
|
||
venv
|
||
~\AppData\Local\pip\Cache
|
||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-pip-
|
||
|
||
- name: Create virtual environment and install dependencies
|
||
shell: powershell
|
||
run: |
|
||
python -m venv venv
|
||
.\venv\Scripts\Activate.ps1
|
||
python -m pip install --upgrade pip
|
||
pip install --no-cache-dir -r requirements.txt
|
||
pip install --no-cache-dir cx_Freeze
|
||
pip install --no-cache-dir yt-dlp
|
||
|
||
- name: Prepare build variables
|
||
shell: powershell
|
||
run: |
|
||
$version = "${{ steps.get_version.outputs.VERSION }}"
|
||
echo "VERSION=$version" >> $env:GITHUB_ENV
|
||
Write-Host "Prepared build variables for version: $version"
|
||
|
||
- name: Build Standard Version (ZIP)
|
||
shell: powershell
|
||
run: |
|
||
.\venv\Scripts\Activate.ps1
|
||
$version = "$env:VERSION"
|
||
Write-Host "Building Standard Version v$version ..."
|
||
|
||
# Clean previous build artifacts
|
||
if (Test-Path "build\exe.*") { Remove-Item "build\exe.*" -Recurse -Force }
|
||
if (Test-Path "build\bdist.*") { Remove-Item "build\bdist.*" -Recurse -Force }
|
||
if (Test-Path "dist") { Remove-Item "dist" -Recurse -Force }
|
||
|
||
# Build executable using cx_Freeze CLI
|
||
cxfreeze main.py `
|
||
--target-dir "dist\YTSage" `
|
||
--base-name Win32GUI `
|
||
--icon "assets\branding\icons\YTSage.ico" `
|
||
--target-name "YTSage-v$version.exe" `
|
||
--optimize 2 `
|
||
--packages "PySide6.QtCore,PySide6.QtGui,PySide6.QtWidgets,requests,PIL,packaging,markdown,playsound3,loguru,setuptools" `
|
||
--excludes "PySide6.QtBluetooth,PySide6.QtNetwork,PySide6.QtOpenGL,PySide6.QtPrintSupport,PySide6.QtSvg,PySide6.QtTest,PySide6.QtXml,PySide6.QtSql,PySide6.QtHelp,PySide6.QtMultimedia,PySide6.QtQml,PySide6.QtQuick,PySide6.QtWebEngineCore,PIL.ImageDraw,PIL.ImageFont,numpy,scipy,wx,pandas,tkinter,yt_dlp,unittest,test,tests" `
|
||
--include-files "src" `
|
||
--include-files "assets"
|
||
|
||
- name: Setup FFmpeg for bundle
|
||
shell: powershell
|
||
run: |
|
||
Write-Host "Setting up FFmpeg for bundled version..."
|
||
|
||
# Create ffmpeg directory
|
||
New-Item -ItemType Directory -Path "ffmpeg-temp" -Force
|
||
|
||
# Download FFmpeg
|
||
$ffmpegUrl = "https://github.com/GyanD/codexffmpeg/releases/download/7.1.1/ffmpeg-7.1.1-full_build.zip"
|
||
Write-Host "Downloading FFmpeg from: $ffmpegUrl"
|
||
Invoke-WebRequest -Uri $ffmpegUrl -OutFile "ffmpeg-temp\ffmpeg.zip"
|
||
|
||
# Extract FFmpeg
|
||
Expand-Archive -Path "ffmpeg-temp\ffmpeg.zip" -DestinationPath "ffmpeg-temp" -Force
|
||
|
||
# Find the extracted directory (GyanD ffmpeg has specific naming)
|
||
$ffmpegDir = Get-ChildItem -Path "ffmpeg-temp" -Directory | Where-Object { $_.Name -like "ffmpeg-*" } | Select-Object -First 1
|
||
|
||
if ($ffmpegDir) {
|
||
# Set environment variable for the build
|
||
$ffmpegBinPath = Join-Path $ffmpegDir.FullName "bin"
|
||
Write-Host "FFmpeg binaries found at: $ffmpegBinPath"
|
||
echo "FFMPEG_PATH=$ffmpegBinPath" >> $env:GITHUB_ENV
|
||
|
||
# Verify files exist
|
||
$ffmpegExe = Join-Path $ffmpegBinPath "ffmpeg.exe"
|
||
$ffprobeExe = Join-Path $ffmpegBinPath "ffprobe.exe"
|
||
$ffplayExe = Join-Path $ffmpegBinPath "ffplay.exe"
|
||
|
||
if (Test-Path $ffmpegExe) {
|
||
Write-Host "[OK] ffmpeg.exe found"
|
||
} else {
|
||
Write-Host "[ERROR] ffmpeg.exe missing"
|
||
}
|
||
if (Test-Path $ffprobeExe) {
|
||
Write-Host "[OK] ffprobe.exe found"
|
||
} else {
|
||
Write-Host "[ERROR] ffprobe.exe missing"
|
||
}
|
||
if (Test-Path $ffplayExe) {
|
||
Write-Host "[OK] ffplay.exe found"
|
||
} else {
|
||
Write-Host "[ERROR] ffplay.exe missing"
|
||
}
|
||
} else {
|
||
Write-Host "Error: Could not find FFmpeg directory after extraction"
|
||
exit 1
|
||
}
|
||
|
||
- name: Build FFmpeg Version (ZIP)
|
||
shell: powershell
|
||
run: |
|
||
.\venv\Scripts\Activate.ps1
|
||
$version = "$env:VERSION"
|
||
Write-Host "Building FFmpeg Version v$version ..."
|
||
|
||
# Clean previous build artifacts
|
||
if (Test-Path "build\exe.*") { Remove-Item "build\exe.*" -Recurse -Force }
|
||
if (Test-Path "build\bdist.*") { Remove-Item "build\bdist.*" -Recurse -Force }
|
||
|
||
# Prepare optional FFmpeg include arguments
|
||
$ffinc1 = ""
|
||
$ffinc2 = ""
|
||
$ffinc3 = ""
|
||
if ($env:FFMPEG_PATH) {
|
||
$ffmpegExe = Join-Path $env:FFMPEG_PATH "ffmpeg.exe"
|
||
$ffprobeExe = Join-Path $env:FFMPEG_PATH "ffprobe.exe"
|
||
$ffplayExe = Join-Path $env:FFMPEG_PATH "ffplay.exe"
|
||
if (Test-Path $ffmpegExe) { $ffinc1 = "--include-files `"$ffmpegExe`"" }
|
||
if (Test-Path $ffprobeExe) { $ffinc2 = "--include-files `"$ffprobeExe`"" }
|
||
if (Test-Path $ffplayExe) { $ffinc3 = "--include-files `"$ffplayExe`"" }
|
||
}
|
||
|
||
# Build executable with FFmpeg using cx_Freeze CLI
|
||
cxfreeze main.py `
|
||
--target-dir "dist\YTSage-FFmpeg" `
|
||
--base-name Win32GUI `
|
||
--icon "assets\branding\icons\YTSage.ico" `
|
||
--target-name "YTSage-v$version-ffmpeg.exe" `
|
||
--optimize 2 `
|
||
--packages "PySide6.QtCore,PySide6.QtGui,PySide6.QtWidgets,requests,PIL,packaging,markdown,playsound3,loguru,setuptools" `
|
||
--excludes "PySide6.QtBluetooth,PySide6.QtNetwork,PySide6.QtOpenGL,PySide6.QtPrintSupport,PySide6.QtSvg,PySide6.QtTest,PySide6.QtXml,PySide6.QtSql,PySide6.QtHelp,PySide6.QtMultimedia,PySide6.QtQml,PySide6.QtQuick,PySide6.QtWebEngineCore,PIL.ImageDraw,PIL.ImageFont,numpy,scipy,wx,pandas,tkinter,yt_dlp,unittest,test,tests" `
|
||
--include-files "src" `
|
||
--include-files "assets" `
|
||
$ffinc1 $ffinc2 $ffinc3
|
||
|
||
- name: Package and prepare release artifacts (ZIPs)
|
||
shell: powershell
|
||
run: |
|
||
$version = "${{ steps.get_version.outputs.VERSION }}"
|
||
|
||
Write-Host "Preparing ZIP artifacts for version: $version"
|
||
New-Item -ItemType Directory -Path "artifacts" -Force
|
||
|
||
# List dist directories
|
||
Write-Host "Files in dist directory:"
|
||
if (Test-Path "dist") {
|
||
Get-ChildItem -Path "dist" -Recurse | ForEach-Object { Write-Host " $($_.FullName)" }
|
||
} else {
|
||
Write-Host " No dist directory found!"
|
||
exit 1
|
||
}
|
||
|
||
# Create Standard ZIP
|
||
$standardDist = Join-Path (Get-Location) "dist\YTSage"
|
||
if (Test-Path $standardDist) {
|
||
$stdZip = "artifacts\YTSage-v$version.zip"
|
||
if (Test-Path $stdZip) { Remove-Item $stdZip -Force }
|
||
Compress-Archive -Path "$standardDist\*" -DestinationPath $stdZip -CompressionLevel Optimal
|
||
Write-Host "Created: $(Resolve-Path $stdZip)"
|
||
} else {
|
||
Write-Host "Warning: Standard dist folder not found at $standardDist"
|
||
}
|
||
|
||
# Create FFmpeg ZIP
|
||
$ffmpegDist = Join-Path (Get-Location) "dist\YTSage-FFmpeg"
|
||
if (Test-Path $ffmpegDist) {
|
||
$ffZip = "artifacts\YTSage-v$version-ffmpeg.zip"
|
||
if (Test-Path $ffZip) { Remove-Item $ffZip -Force }
|
||
Compress-Archive -Path "$ffmpegDist\*" -DestinationPath $ffZip -CompressionLevel Optimal
|
||
Write-Host "Created: $(Resolve-Path $ffZip)"
|
||
} else {
|
||
Write-Host "Warning: FFmpeg dist folder not found at $ffmpegDist"
|
||
}
|
||
|
||
# List all artifacts
|
||
Write-Host "Final artifacts:"
|
||
if (Test-Path "artifacts") {
|
||
$artifactFiles = Get-ChildItem artifacts
|
||
if ($artifactFiles) {
|
||
$artifactFiles | ForEach-Object { Write-Host " $($_.Name)" }
|
||
} else {
|
||
Write-Host " No artifacts created!"
|
||
}
|
||
} else {
|
||
Write-Host " Artifacts directory not found!"
|
||
}
|
||
|
||
- name: Create draft release
|
||
uses: softprops/action-gh-release@v1
|
||
with:
|
||
tag_name: ${{ github.ref_name }}
|
||
name: YTSage ${{ github.ref_name }}
|
||
draft: true
|
||
prerelease: false
|
||
body: |
|
||
# YTSage ${{ github.ref_name }}
|
||
|
||
**Release Date**: ${{ github.event.head_commit.timestamp }}
|
||
|
||
## Downloads
|
||
|
||
### Standard Version (ZIP)
|
||
- **YTSage-v${{ steps.get_version.outputs.VERSION }}.zip** – Portable ZIP (downloads FFmpeg on first use if needed)
|
||
|
||
### FFmpeg Bundle Version (ZIP)
|
||
- **YTSage-v${{ steps.get_version.outputs.VERSION }}-ffmpeg.zip** – Portable ZIP with FFmpeg included
|
||
|
||
## Installation / Usage
|
||
|
||
1. Download the `.zip` file you want.
|
||
2. Right-click the ZIP, choose Properties, and if you see "Unblock", check it and Apply.
|
||
3. Extract the ZIP to a folder (e.g., `C:\Apps\YTSage`).
|
||
4. Run `YTSage-v${{ steps.get_version.outputs.VERSION }}.exe` inside the extracted folder.
|
||
|
||
## System Requirements
|
||
|
||
- Windows 10/11 (64-bit)
|
||
- Internet connection for yt-dlp updates
|
||
|
||
## Notes
|
||
|
||
- **Standard version**: Downloads FFmpeg automatically when needed.
|
||
- **FFmpeg bundle**: Includes FFmpeg binaries for offline use.
|
||
|
||
---
|
||
|
||
**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ github.ref_name }}
|
||
files: |
|
||
artifacts/*
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |