Skip to content

Build Windows

Build Windows #3

Workflow file for this run

# Build Windows (x86_64, MSYS2/MinGW)
# Output: Portable zip + installer published to Dropbox.
name: Build Windows
on:
workflow_dispatch:
workflow_call:
outputs:
zip_url:
description: Dropbox direct URL for rolling zip (pylux-latest or pylux-beta-latest on release/beta)
value: ${{ jobs.build-windows_x64-msys2.outputs.zip_url }}
installer_url:
description: Dropbox direct URL for rolling installer (installer-latest or installer-beta-latest on release/beta)
value: ${{ jobs.build-windows_x64-msys2.outputs.installer_url }}
chiaki_version:
description: Pylux version from CMakeLists.txt
value: ${{ jobs.build-windows_x64-msys2.outputs.chiaki_version }}
concurrency:
group: build-windows-${{ github.ref }}
cancel-in-progress: true
env:
CHIAKI_ENABLE_STEAMWORKS: "OFF"
jobs:
build-windows_x64-msys2:
name: Build Pylux Windows x86_64
runs-on: windows-latest
outputs:
zip_url: ${{ steps.zip.outputs.url }}
installer_url: ${{ steps.installer.outputs.url }}
chiaki_version: ${{ steps.extract_version.outputs.version }}
defaults:
run:
shell: msys2 {0}
steps:
- name: Disable autocrlf
shell: pwsh
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: msys2/setup-msys2@v2
with:
msystem: mingw64
update: true
install: git
pacboy: >-
ca-certificates:p
cc:p
cmake:p
curl:p
diffutils:p
fast_float:p
fftw:p
hidapi:p
json-c:p
lcms2:p
libdovi:p
meson:p
miniupnpc:p
gcc:p
nasm:p
ninja:p
openssl:p
opus:p
pkgconf:p
protobuf:p
python:p
python-psutil:p
python-glad:p
python-jinja:p
python-pip:p
qt6-base:p
qt6-declarative:p
qt6-svg:p
SDL2:p
shaderc:p
speexdsp:p
spirv-cross:p
vulkan:p
vulkan-headers:p
- name: Install python protobuf and zip
run: |
pip install protobuf
pacman -S git make unzip zip jq --noconfirm
- name: Build libbplacebo
run: |
scripts/build-libplacebo-windows.sh
- name: Setup ffmpeg
run: |
curl -LO https://github.com/streetpea/FFmpeg-Builds/releases/download/latest/ffmpeg-n7.1-latest-win64-gpl-shared-7.1.zip
unzip ffmpeg-n7.1-latest-win64-gpl-shared-7.1.zip
cp -a "ffmpeg-n7.1-latest-win64-gpl-shared-7.1/bin/." /mingw64/bin
cp -a "ffmpeg-n7.1-latest-win64-gpl-shared-7.1/include/." /mingw64/include
cp -a "ffmpeg-n7.1-latest-win64-gpl-shared-7.1/lib/." /mingw64/lib
- name: Add QmlWebEngine Import
run: |
cp scripts/qtwebengine_import.qml gui/src/qml/
- name: Configure Pylux
run: |
cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DCHIAKI_ENABLE_CLI=OFF -DCHIAKI_ENABLE_STEAMWORKS=${{ env.CHIAKI_ENABLE_STEAMWORKS }} -DCHIAKI_ENABLE_STEAM_SHORTCUT=ON
- name: Build Pylux
run: |
cmake --build build --config Release --clean-first --target chiaki
- name: Package Pylux
run: |
mkdir pylux
cp build/gui/chiaki.exe pylux/pylux.exe
if [ "${{ env.CHIAKI_ENABLE_STEAMWORKS }}" = "ON" ]; then
cp third-party/steamworks/steamworks_sdk/redistributable_bin/win64/steam_api64.dll pylux/
cp steam_appid.txt pylux/ 2>/dev/null || echo "Warning: steam_appid.txt not found"
fi
export PATH="${{ github.workspace }}/build/third-party/cpp-steam-tools:/mingw64/share/qt6/bin/:/mingw64/bin/:${PATH}"
export QT_PLUGIN_PATH="/mingw64/share/qt6/plugins"
export QML2_IMPORT_PATH="/mingw64/share/qt6/qml"
copy_dll_dep() {
for dep; do
case "$dep" in
""|*"/Windows/"*|*"/WINDOWS/"*|*"/System32/"*|*"/SYSTEM32/"*|*"/SysWOW64/"*|*"/SYSWOW64/"*)
continue
;;
esac
if [ -f "$dep" ] && [ ! -e "pylux/${dep##*/}" ]; then
echo "Copied $dep"
cp "$dep" pylux/
echo "$dep" >> tmp0.txt
fi
done
}
# Recursively find and copy DLL dependencies of pylux.exe
echo pylux/pylux.exe > tmp0.txt
while [ -e tmp0.txt ]
do
cp tmp0.txt tmp.txt
rm tmp0.txt
sort -u tmp.txt -o tmp.txt
ldd $(<tmp.txt) | awk '($2 == "=>") { print $3 }' | xargs -r copy_dll_dep
done
# Copy Qt plugins and QML modules
windeployqt6.exe --no-translations --qmldir=gui/src/qml pylux/pylux.exe
# Copy dependencies of Qt plugins (windeployqt6 doesn't copy plugin dependencies like libjpeg-8.dll)
echo "Finding Qt plugin DLLs..."
find pylux -type d \( -name plugins -o -name imageformats -o -name platforms -o -name sqldrivers \) -exec find {} -name "*.dll" \; | while read plugin; do
echo "Found plugin: $plugin"
echo "$plugin" >> tmp0.txt
done
echo "Copying plugin dependencies..."
while [ -e tmp0.txt ] && [ -s tmp0.txt ]
do
cp tmp0.txt tmp.txt
rm tmp0.txt
sort -u tmp.txt -o tmp.txt
ldd $(<tmp.txt) 2>/dev/null | awk '($2 == "=>") { print $3 }' | while read -r dep; do
case "$dep" in
""|*"/Windows/"*|*"/WINDOWS/"*|*"/System32/"*|*"/SYSTEM32/"*|*"/SysWOW64/"*|*"/SYSWOW64/"*)
continue
;;
esac
if [ -f "$dep" ] && [ ! -e "pylux/${dep##*/}" ]; then
echo " Copying plugin dependency: ${dep##*/}"
cp "$dep" pylux/
echo "$dep" >> tmp0.txt
fi
done
done
rm -f tmp0.txt tmp.txt
- name: Create zip archive
run: |
zip -r pylux.zip pylux
echo "RELEASE_PACKAGE_PATH=pylux.zip" >> $GITHUB_ENV
- name: Extract version
id: extract_version
uses: ./.github/actions/extract-version
- name: Compile .ISS to .EXE Installer
uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
with:
path: "scripts/chiaki-ng.iss"
options: /O+
- name: Rename installer with version
run: |
INSTALLER_NAME="pylux-windows-installer-${{ env.CHIAKI_VERSION }}.exe"
cp pylux-windows-installer.exe "${INSTALLER_NAME}"
echo "INSTALLER_NAME=${INSTALLER_NAME}" >> $GITHUB_ENV
echo "Renamed installer to: ${INSTALLER_NAME}"
- name: Publish portable zip
id: zip
uses: ./.github/actions/dropbox-publish
with:
file: ${{ env.RELEASE_PACKAGE_PATH }}
latest-path: /pylux/windows/pylux${{ github.ref_name == 'release/beta' && '-beta' || '' }}-latest.zip
versioned-path: /pylux/windows/pylux-${{ env.CHIAKI_VERSION }}.zip
refresh-token: ${{ secrets.DROPBOX_REFRESH_TOKEN }}
app-key: ${{ secrets.DROPBOX_APP_KEY }}
app-secret: ${{ secrets.DROPBOX_APP_SECRET }}
- name: Publish installer
id: installer
uses: ./.github/actions/dropbox-publish
with:
file: ${{ env.INSTALLER_NAME }}
latest-path: /pylux/windows/pylux-windows-installer${{ github.ref_name == 'release/beta' && '-beta' || '' }}-latest.exe
versioned-path: /pylux/windows/pylux-windows-installer-${{ env.CHIAKI_VERSION }}.exe
refresh-token: ${{ secrets.DROPBOX_REFRESH_TOKEN }}
app-key: ${{ secrets.DROPBOX_APP_KEY }}
app-secret: ${{ secrets.DROPBOX_APP_SECRET }}
- name: Build summary
if: always()
run: |
ZIP_SIZE=$(ls -lh "${{ env.RELEASE_PACKAGE_PATH }}" 2>/dev/null | awk '{print $5}')
INST_SIZE=$(ls -lh "${{ env.INSTALLER_NAME }}" 2>/dev/null | awk '{print $5}')
if [ "${{ github.ref_name }}" = "release/beta" ]; then
ROLLING_LABEL="rolling (beta: pylux-beta-latest.* / installer-beta-latest)"
ZIP_NAME="pylux-beta-latest.zip"
INST_NAME="pylux-windows-installer-beta-latest.exe"
else
ROLLING_LABEL="rolling (stable: pylux-latest.* / installer-latest)"
ZIP_NAME="pylux-latest.zip"
INST_NAME="pylux-windows-installer-latest.exe"
fi
{
echo "## Pylux Windows — v${CHIAKI_VERSION}"
echo ""
echo "| Artifact | Size | Download (${ROLLING_LABEL}) | Versioned archive |"
echo "| --- | --- | --- | --- |"
echo "| Portable zip | ${ZIP_SIZE:-?} | [${ZIP_NAME}](${{ steps.zip.outputs.url }}) | \`/pylux/windows/pylux-${CHIAKI_VERSION}.zip\` |"
echo "| Installer (.exe) | ${INST_SIZE:-?} | [${INST_NAME}](${{ steps.installer.outputs.url }}) | \`/pylux/windows/pylux-windows-installer-${CHIAKI_VERSION}.exe\` |"
echo ""
echo "### How to use"
echo "- **Portable zip** — unzip anywhere and run \`pylux.exe\`. No install required."
echo "- **Installer (.exe)** — run and follow the prompts; adds Start Menu shortcuts."
} >> "$GITHUB_STEP_SUMMARY"