Files
Warlock-Studio-Universal/.gitea/workflows/release.yml
T
vlad.os 586160b1a0
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
Add Gitea Actions CI/CD pipeline
- .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
2026-06-27 03:26:18 +03:00

284 lines
9.4 KiB
YAML

# =============================================================================
# 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