Add Gitea Actions CI/CD pipeline
Build and Release / Validate source (push) Failing after 25s
Build and Release / Build (linux) (push) Has been skipped
Build and Release / Create Release (push) Has been skipped
Build and Release / Build (windows) (push) Has been skipped

- .gitea/workflows/release.yml — multi-platform build (linux native + windows cross via wine)
- requirements.txt — all pip dependencies with version pins
- PKGBUILD — Arch Linux build reference
- build-scripts/build-linux-portable.sh — Linux portable/AppImage builder
- build-scripts/build-windows.ps1 — Windows PyInstaller + Inno Setup builder
This commit is contained in:
2026-06-27 03:26:18 +03:00
parent 4886f06d36
commit 586160b1a0
5 changed files with 704 additions and 0 deletions
+283
View File
@@ -0,0 +1,283 @@
# =============================================================================
# Warlock Studio — Gitea Actions CI/CD Pipeline
# =============================================================================
name: Build and Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., 6.0.1)'
required: true
dry_run:
description: 'Dry run — build but do not create a release'
type: boolean
default: false
env:
APP_NAME: Warlock-Studio
PYTHON_VERSION: '3.10'
PYTHON_WIN_URL: 'https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe'
jobs:
# ==========================================================================
# VALIDATE — syntax + lint before building
# ==========================================================================
validate:
name: Validate source
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller pyflakes
- name: Syntax check
run: |
python -m pyflakes *.py
python -m compileall -q *.py
- name: Verify .spec
run: |
python -c "
with open('Warlock-Studio.spec') as f:
c = f.read()
assert 'Analysis' in c
assert 'EXE' in c
print('OK .spec valid')
"
# ==========================================================================
# BUILD — matrix: linux (native) + windows (cross via wine)
# ==========================================================================
build:
name: Build (${{ matrix.target }})
needs: [validate]
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
target: [linux, windows]
steps:
- uses: actions/checkout@v4
# ---- Common: Setup Python ----
- name: Setup Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install common system deps
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq libgl1-mesa-glx libegl1 libxkbcommon0 file
- name: Install Python deps
run: |
python -m pip install --upgrade pip wheel setuptools
pip install -r requirements.txt
pip install pyinstaller
# ---- Linux: native build ----
- name: Build Linux native (PyInstaller)
if: matrix.target == 'linux'
run: pyinstaller Warlock-Studio.spec --noconfirm
- name: Package Linux (tar.gz)
if: matrix.target == 'linux'
run: |
v="${{ github.ref_name }}" && v="${v#v}"
[ "${{ github.event_name }}" = "workflow_dispatch" ] && v="${{ github.event.inputs.version }}"
[ -z "$v" ] && v="dev"
a="${{ env.APP_NAME }}-${v}-linux-x64.tar.gz"
tar -czf "${a}" -C dist "${{ env.APP_NAME }}"
echo "ARCHIVE_NAME=${a}" >> $GITHUB_ENV
- name: Verify Linux binary
if: matrix.target == 'linux'
run: |
ls -lh "dist/${{ env.APP_NAME }}/${{ env.APP_NAME }}"
file "dist/${{ env.APP_NAME }}/${{ env.APP_NAME }}"
# ---- Windows: cross-build via Wine ----
- name: Install Wine + Windows Python
if: matrix.target == 'windows'
run: |
sudo dpkg --add-architecture i386
sudo apt-get update -qq
sudo apt-get install -y -qq wine wine32 wine64 xvfb
# Download Windows Python into stable location
mkdir -p /tmp/winbuild
wget -q "${{ env.PYTHON_WIN_URL }}" -O /tmp/winbuild/python-installer.exe
- name: Setup Windows Python under Wine
if: matrix.target == 'windows'
run: |
export DISPLAY=:99
Xvfb :99 -screen 0 1024x768x16 &>/dev/null &
sleep 1
# Install Python for Windows silently
wine /tmp/winbuild/python-installer.exe \
/quiet InstallAllUsers=1 PrependPath=1 \
Include_doc=0 Include_tcltk=1 \
TargetDir='C:\Python310' 2>&1 | tail -5
# Verify
wine python --version 2>&1
wine pip --version 2>&1
- name: Install Windows dependencies under Wine
if: matrix.target == 'windows'
run: |
# Map project directory as Windows drive
WINEPROJ="Z:$(pwd)"
# Install pip deps
wine pip install --no-input --no-cache-dir \
-r "${WINEPROJ}/requirements.txt" 2>&1 | tail -5
wine pip install --no-input --no-cache-dir \
pyinstaller onnxruntime-directml 2>&1 | tail -5
- name: Build Windows binary (PyInstaller via Wine)
if: matrix.target == 'windows'
run: |
WINEPROJ="Z:$(pwd)"
wine pyinstaller "${WINEPROJ}/Warlock-Studio.spec" \
--noconfirm --distpath "${WINEPROJ}/dist" 2>&1 | tail -10
- name: Verify Windows binary
if: matrix.target == 'windows'
run: |
ls -lh "dist/${{ env.APP_NAME }}/${{ env.APP_NAME }}.exe"
file "dist/${{ env.APP_NAME }}/${{ env.APP_NAME }}.exe"
- name: Package Windows (ZIP)
if: matrix.target == 'windows'
run: |
v="${{ github.ref_name }}" && v="${v#v}"
[ "${{ github.event_name }}" = "workflow_dispatch" ] && v="${{ github.event.inputs.version }}"
[ -z "$v" ] && v="dev"
a="${{ env.APP_NAME }}-${v}-win64.zip"
cd dist
zip -r "${a}" "${{ env.APP_NAME }}"
cd ..
mv "dist/${a}" .
echo "ARCHIVE_NAME=${a}" >> $GITHUB_ENV
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}-${{ matrix.target }}
path: ${{ env.ARCHIVE_NAME }}
# ==========================================================================
# RELEASE — create Gitea release + attach binaries
# ==========================================================================
release:
name: Create Release
needs: [build]
runs-on: ubuntu-22.04
if: github.event_name != 'workflow_dispatch' || !github.event.inputs.dry_run
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
pattern: ${{ env.APP_NAME }}-*
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -lh artifacts/
- name: Determine version
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
v="${{ github.ref_name }}" && echo "version=${v#v}" >> $GITHUB_OUTPUT
fi
- name: Prepare release notes
run: |
if [ -f CHANGELOG.md ]; then
awk '/^## /{if(c) exit; c=1; next} c' CHANGELOG.md > release-notes.md 2>/dev/null || true
fi
[ -s release-notes.md ] || echo "Release ${{ steps.version.outputs.tag }}" > release-notes.md
- name: Create Gitea Release
id: create_release
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
BODY=$(cat release-notes.md | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")
PAYLOAD='{
"tag_name": "${{ steps.version.outputs.tag }}",
"target_commitish": "${{ github.sha }}",
"name": "Warlock Studio ${{ steps.version.outputs.version }}",
"body": '"${BODY}"',
"draft": false,
"prerelease": false
}'
RESP=$(curl -s -X POST \
-H "Authorization: token ${RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
-d "${PAYLOAD}" \
"${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases")
ID=$(echo "${RESP}" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" 2>/dev/null || echo "")
if [ -z "${ID}" ]; then
echo "ERROR creating release:"
echo "${RESP}"
exit 1
fi
echo "release_id=${ID}" >> $GITHUB_OUTPUT
echo "Release ID: ${ID}"
- name: Upload assets to release
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
ID="${{ steps.create_release.outputs.release_id }}"
URL="${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases/${ID}/assets"
for a in artifacts/*; do
[ -f "${a}" ] || continue
fname=$(basename "${a}")
echo "Uploading: ${fname} ($(stat -c%s "${a}") bytes)"
curl -s -X POST \
-H "Authorization: token ${RELEASE_TOKEN}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@${a}" \
"${URL}?name=${fname}" > /dev/null
if [ $? -eq 0 ]; then
echo " OK"
else
echo " FAIL"
fi
done
+103
View File
@@ -0,0 +1,103 @@
# Maintainer: Warlock Studio <negroayub97@gmail.com>
# Contributor: Ivan Ayub
# Arch Linux PKGBUILD — builds Warlock Studio from source using PyInstaller
# =============================================================================
# This PKGBUILD is provided for reference / self-build. For AUR submission
# replace pkgver() with the actual release tag and uncomment source=() array.
# =============================================================================
pkgname=warlock-studio
pkgver=6.0
pkgrel=1
pkgdesc="AI-powered video upscaling, restoration, denoising and frame interpolation"
arch=('x86_64')
url="https://github.com/Ivan-Ayub97/Warlock-Studio"
license=('MIT')
depends=(
'python'
'python-pip'
'python-customtkinter'
'python-opencv'
'python-numpy'
'python-pillow'
'python-moviepy'
'python-natsort'
'python-packaging'
'python-psutil'
'python-requests'
'python-tkinterdnd2'
'tk'
'onnxruntime-opt' # or onnxruntime for CPU-only
'ffmpeg'
'libxkbcommon'
'libxcb'
'libgl'
)
makedepends=(
'python-build'
'python-installer'
'python-wheel'
'python-pyinstaller'
)
optdepends=(
'python-onnxruntime-opt: GPU-accelerated ONNX inference (CUDA)'
'python-onnxruntime-directml: DirectML backend for Windows (not applicable)'
)
conflicts=()
provides=("${pkgname}")
source=("${pkgname}-${pkgver}.tar.gz::${url}/archive/v${pkgver}.tar.gz")
sha256sums=('SKIP')
validpgpkeys=()
build() {
cd "${srcdir}/${pkgname}-${pkgver}"
# Install Python dependencies into temporary venv for PyInstaller
python -m venv --system-site-packages _buildenv
source _buildenv/bin/activate
pip install --no-input --no-cache-dir -r requirements.txt
pip install --no-input --no-cache-dir pyinstaller
# Build with PyInstaller
pyinstaller Warlock-Studio.spec --noconfirm
deactivate
rm -rf _buildenv
}
package() {
cd "${srcdir}/${pkgname}-${pkgver}"
# Install into /opt/warlock-studio
install -dm755 "${pkgdir}/opt/warlock-studio"
cp -r dist/Warlock-Studio/* "${pkgdir}/opt/warlock-studio/"
# Desktop entry
install -dm755 "${pkgdir}/usr/share/applications"
cat > "${pkgdir}/usr/share/applications/warlock-studio.desktop" << EOF
[Desktop Entry]
Name=Warlock Studio
Comment=AI-powered video upscaling, restoration and frame interpolation
Exec=/opt/warlock-studio/Warlock-Studio
Icon=warlock-studio
Terminal=false
Type=Application
Categories=Graphics;Video;AudioVideo;
StartupWMClass=Warlock-Studio
EOF
# Icon
install -dm755 "${pkgdir}/usr/share/icons/hicolor/256x256/apps"
install -m644 logo.ico "${pkgdir}/usr/share/icons/hicolor/256x256/apps/warlock-studio.ico" 2>/dev/null || true
# Symlink to PATH
install -dm755 "${pkgdir}/usr/bin"
ln -sf "/opt/warlock-studio/Warlock-Studio" "${pkgdir}/usr/bin/warlock-studio"
# License
install -dm755 "${pkgdir}/usr/share/licenses/${pkgname}"
install -m644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/" 2>/dev/null || true
}
# vim:set ts=2 sw=2 et:
+133
View File
@@ -0,0 +1,133 @@
#!/usr/bin/env bash
# =============================================================================
# Warlock Studio — Linux Portable Build Script
# =============================================================================
# Builds a portable AppDir/AppImage or tar.gz of the PyInstaller output.
#
# Usage:
# ./build-scripts/build-linux-portable.sh [--appimage] [--output-dir=./dist]
#
# Requires: python3, pip, pyinstaller, (optional: appimagetool for --appimage)
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
APP_NAME="Warlock-Studio"
BUILD_DIR="dist"
OUTPUT_DIR="${PROJECT_DIR}/${BUILD_DIR}"
# ---- Parse arguments ----
BUILD_APPIMAGE=false
while [[ $# -gt 0 ]]; do
case "$1" in
--appimage) BUILD_APPIMAGE=true; shift ;;
--output-dir=*) OUTPUT_DIR="${1#*=}"; shift ;;
--output-dir) OUTPUT_DIR="$2"; shift 2 ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
echo "=========================================="
echo " Warlock Studio — Linux Build"
echo "=========================================="
# ---- Step 1: Install system dependencies ----
echo "[1/5] Checking system dependencies..."
for cmd in python3 pip3; do
if ! command -v "$cmd" &>/dev/null; then
echo "ERROR: $cmd not found. Install python3 and pip."
exit 1
fi
done
# ---- Step 2: Install Python dependencies ----
echo "[2/5] Installing Python dependencies..."
pip3 install --upgrade pip wheel setuptools
pip3 install -r "${PROJECT_DIR}/requirements.txt"
pip3 install pyinstaller
# ---- Step 3: Build with PyInstaller ----
echo "[3/5] Building with PyInstaller..."
pyinstaller "${PROJECT_DIR}/Warlock-Studio.spec" --noconfirm --distpath "${OUTPUT_DIR}"
# Verify the binary was created
if [ -f "${OUTPUT_DIR}/${APP_NAME}/${APP_NAME}" ]; then
echo " Binary: ${OUTPUT_DIR}/${APP_NAME}/${APP_NAME}"
file "${OUTPUT_DIR}/${APP_NAME}/${APP_NAME}"
elif [ -f "${OUTPUT_DIR}/${APP_NAME}/${APP_NAME}.exe" ]; then
echo " Binary: ${OUTPUT_DIR}/${APP_NAME}/${APP_NAME}.exe"
else
echo "ERROR: Build output not found at ${OUTPUT_DIR}/${APP_NAME}/"
ls -la "${OUTPUT_DIR}/${APP_NAME}" 2>/dev/null || echo " (directory missing)"
exit 1
fi
# ---- Step 4: Create portable tar.gz ----
echo "[4/5] Creating portable tar.gz..."
VERSION=""
if [ -n "${CI_COMMIT_TAG:-}" ]; then
VERSION="${CI_COMMIT_TAG#v}"
elif command -v git &>/dev/null; then
VERSION="$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0")"
VERSION="${VERSION#v}"
fi
[ -z "$VERSION" ] && VERSION="dev"
ARCHIVE_NAME="${APP_NAME}-${VERSION}-linux-x64.tar.gz"
tar -czf "${ARCHIVE_NAME}" -C "${OUTPUT_DIR}" "${APP_NAME}"
echo " Archive: ${ARCHIVE_NAME} ($(du -h "${ARCHIVE_NAME}" | cut -f1))"
# ---- Step 5: Optionally build AppImage ----
if [ "$BUILD_APPIMAGE" = true ]; then
echo "[5/5] Creating AppImage..."
if ! command -v appimagetool &>/dev/null && [ ! -f "appimagetool" ]; then
echo " Downloading appimagetool..."
wget -q "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -O appimagetool
chmod +x appimagetool
fi
APPIMAGETOOL=$(command -v appimagetool || echo "./appimagetool")
# Create AppDir structure
APPDIR="${OUTPUT_DIR}/${APP_NAME}.AppDir"
mkdir -p "${APPDIR}/usr/bin"
cp -r "${OUTPUT_DIR}/${APP_NAME}"/* "${APPDIR}/usr/bin/"
# Create desktop entry
cat > "${APPDIR}/${APP_NAME}.desktop" << EOF
[Desktop Entry]
Name=Warlock Studio
Comment=AI-powered video upscaling, restoration and frame interpolation
Exec=${APP_NAME}
Icon=${APP_NAME}
Terminal=false
Type=Application
Categories=Graphics;Video;
EOF
# Copy icon
cp "${PROJECT_DIR}/logo.ico" "${APPDIR}/${APP_NAME}.png" 2>/dev/null || true
# Create AppRun
cat > "${APPDIR}/AppRun" << 'APPRUN_EOF'
#!/usr/bin/env bash
HERE="$(dirname "$(readlink -f "$0")")"
export PATH="${HERE}/usr/bin:${PATH}"
export LD_LIBRARY_PATH="${HERE}/usr/bin/_internal:${LD_LIBRARY_PATH}"
exec "${HERE}/usr/bin/Warlock-Studio" "$@"
APPRUN_EOF
chmod +x "${APPDIR}/AppRun"
# Build AppImage
ARCH=x86_64 "$APPIMAGETOOL" "${APPDIR}" "${APP_NAME}-${VERSION}-x86_64.AppImage"
echo " AppImage: ${APP_NAME}-${VERSION}-x86_64.AppImage"
fi
echo ""
echo "=========================================="
echo " BUILD COMPLETE"
echo "=========================================="
echo "Output: ${ARCHIVE_NAME}"
[ "$BUILD_APPIMAGE" = true ] && echo "AppImage: ${APP_NAME}-${VERSION}-x86_64.AppImage"
+102
View File
@@ -0,0 +1,102 @@
# =============================================================================
# Warlock Studio — Windows Build Script (PowerShell)
# =============================================================================
# Builds with PyInstaller and optionally packages into an installer via Inno Setup.
#
# Usage:
# .\build-scripts\build-windows.ps1 [-InnoSetup] [-OutputDir .\dist]
#
# Requires: Python 3.10+, pip, PyInstaller
# Optional: Inno Setup (for -InnoSetup flag)
# =============================================================================
param(
[switch]$InnoSetup,
[string]$OutputDir = (Join-Path (Get-Location) "dist")
)
$ErrorActionPreference = "Stop"
$ProjectRoot = Split-Path -Parent (Split-Path -Parent $PSCommandPath)
$AppName = "Warlock-Studio"
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host " Warlock Studio — Windows Build" -ForegroundColor Cyan
Write-Host "==========================================" -ForegroundColor Cyan
# ---- Step 1: Install Python dependencies ----
Write-Host "[1/5] Installing Python dependencies..." -ForegroundColor Yellow
python -m pip install --upgrade pip wheel setuptools
pip install -r (Join-Path $ProjectRoot "requirements.txt")
pip install pyinstaller onnxruntime-directml
# ---- Step 2: Build with PyInstaller ----
Write-Host "[2/5] Building with PyInstaller..." -ForegroundColor Yellow
$specFile = Join-Path $ProjectRoot "Warlock-Studio.spec"
$distPath = $OutputDir
pyinstaller $specFile --noconfirm --distpath $distPath
# Verify output
$binaryPath = Join-Path $distPath $AppName "$AppName.exe"
if (-not (Test-Path $binaryPath)) {
Write-Error "Build failed: $binaryPath not found"
exit 1
}
Write-Host " Binary: $binaryPath" -ForegroundColor Green
# ---- Step 3: Create versioned archive ----
Write-Host "[3/5] Creating ZIP archive..." -ForegroundColor Yellow
$version = "dev"
$tag = git describe --tags --abbrev=0 2>$null
if ($tag) { $version = $tag.TrimStart('v') }
$archiveName = "$AppName-$version-win64.zip"
$archivePath = Join-Path $ProjectRoot $archiveName
$buildDir = Join-Path $distPath $AppName
Compress-Archive -Path "$buildDir\*" -DestinationPath $archivePath -Force
Write-Host " Archive: $archivePath" -ForegroundColor Green
# ---- Step 4: Build Inno Setup installer (optional) ----
if ($InnoSetup) {
Write-Host "[4/5] Building Inno Setup installer..." -ForegroundColor Yellow
# Check if ISCC is available
$iscc = Get-Command "iscc" -ErrorAction SilentlyContinue
if (-not $iscc) {
$possiblePaths = @(
"${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe",
"${env:ProgramFiles}\Inno Setup 6\ISCC.exe",
"${env:ProgramFiles(x86)}\Inno Setup 5\ISCC.exe"
)
$isccPath = $possiblePaths | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $isccPath) {
Write-Warning "Inno Setup not found. Skipping installer build."
Write-Warning " Install from: https://jrsoftware.org/isdl.php"
} else {
$iscc = $isccPath
}
}
if ($iscc) {
$issFile = Join-Path $ProjectRoot "Setup.iss"
if (Test-Path $issFile) {
& $iscc $issFile
Write-Host " Installer built." -ForegroundColor Green
} else {
Write-Warning "Setup.iss not found. Skipping installer."
}
}
} else {
Write-Host "[4/5] Skipped (use -InnoSetup to build installer)" -ForegroundColor Gray
}
# ---- Step 5: Cleanup ----
Write-Host "[5/5] Cleanup..." -ForegroundColor Yellow
Remove-Item -Recurse -Force "build" -ErrorAction SilentlyContinue
Write-Host ""
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host " BUILD COMPLETE" -ForegroundColor Cyan
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host "Output: $archiveName" -ForegroundColor Green
if ($InnoSetup -and $iscc) {
Write-Host "Installer: Output\Warlock-Studio-$version-Full-Installer.exe" -ForegroundColor Green
}
+83
View File
@@ -0,0 +1,83 @@
# =============================================================================
# Warlock Studio — Python Dependencies
# =============================================================================
# Platform: Python 3.10+
# Framework: CustomTkinter GUI, OpenCV + ONNX Runtime for AI media processing
# =============================================================================
# ---------------------------------------------------------------------------
# SECTION 1 — Core Runtime Dependencies
# ---------------------------------------------------------------------------
# GUI framework — modern, themed tkinter widgets
customtkinter>=5.2.2
# OpenCV — image/video I/O, color conversion, resizing, frame manipulation
opencv-python>=4.8.1.78
# NumPy — multidimensional array backend for OpenCV, ONNX, and image ops
numpy>=1.24.0
# ONNX Runtime — AI model inference (upscaling, restoration, frame interpolation)
onnxruntime>=1.16.0
# Pillow — PILLow Image loading for GUI thumbnails and splash screen
Pillow>=10.2.0
# MoviePy — video clip assembly from processed image sequences
moviepy>=1.0.3
# ---------------------------------------------------------------------------
# SECTION 2 — Utility Dependencies
# ---------------------------------------------------------------------------
# natsort — natural (human-friendly) sorting of file names
natsort>=8.4.0
# packaging — PEP 440 version comparison for update checks
packaging>=23.2
# psutil — system resource monitoring (RAM, CPU) for adaptive processing
psutil>=5.9.8
# requests — HTTP client for update checks and online features
requests>=2.31.0
# tkinterdnd2 — drag-and-drop support for the GUI
tkinterdnd2>=0.3.0
# ---------------------------------------------------------------------------
# SECTION 3 — Optional / Platform-Specific Backends
# ---------------------------------------------------------------------------
# OpenCV headless (no GUI) — use instead of opencv-python on Linux servers
# or headless environments where no display is available.
# pip install opencv-python-headless
# opencv-python-headless>=4.8.1.78
# ONNX Runtime with DirectML — Windows-only, enables GPU inference via
# DirectML for AMD, Intel, and NVIDIA GPUs without CUDA.
# pip install onnxruntime-directml
# onnxruntime-directml>=1.16.0
# ONNX Runtime with CUDA — NVIDIA GPU acceleration via CUDA 11.x/12.x.
# Requires matching CUDA runtime and cuDNN installed on the system.
# pip install onnxruntime-gpu
# onnxruntime-gpu>=1.16.0
# wmi — Windows Management Instrumentation (GPU info on Windows).
# Optional; only used if available.
# wmi>=1.5.1
# GPUtil — NVIDIA GPU information (Linux/Windows).
# Optional; only used if available.
# GPUtil>=1.4.0
# ---------------------------------------------------------------------------
# SECTION 4 — Build / Packaging
# ---------------------------------------------------------------------------
# PyInstaller — bundle the application into a standalone executable.
# Install separately from runtime deps (build step only).
# pip install pyinstaller
# pyinstaller>=6.3.0