diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 7f4b3f6..1c41f09 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -33,26 +33,22 @@ jobs: path: psp-preserve-linux-x86_64.tar.gz windows: - name: Windows x64 + name: Windows x64 (Wine) runs-on: windows steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - name: Install build dependencies run: | - python -m pip install --upgrade pip - pip install -r requirements-build.txt + winpython -m pip install --upgrade pip + winpython -m pip install -r requirements-build.txt - name: Build - run: pyinstaller --clean --noconfirm psp-preserve.spec + run: winpython -m PyInstaller --clean --noconfirm psp-preserve.spec - name: Package zip - shell: pwsh - run: Compress-Archive -Path dist\psp-preserve -DestinationPath psp-preserve-windows-x64.zip + run: | + cd dist && zip -rq ../psp-preserve-windows-x64.zip psp-preserve - uses: actions/upload-artifact@v4 with: diff --git a/README.md b/README.md index c464f78..82b0a36 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,24 @@ act_runner.exe register \ The registration token is generated in Gitea under **Site Administration → Actions → Runners → Create new runner**. +#### Windows builds without a Windows box (Wine runner) + +The `windows` job targets a runner labelled `windows` that builds under Wine on +Linux. Build it from `runner/`: + +```bash +docker build -f runner/Dockerfile -t psp-wine-runner . +docker run -d --name psp-wine-runner --restart unless-stopped \ + -e GITEA_INSTANCE_URL=https://git.ceaf.dev \ + -e GITEA_RUNNER_REGISTRATION_TOKEN= \ + -v /mnt/user/appdata/psp-wine-runner:/data \ + psp-wine-runner +``` + +The image ships Wine + Windows CPython 3.12 + PyInstaller, and registers itself +with the `windows:host` label. (If you have a real Windows machine instead, +register a native `act_runner.exe` with the same `windows` label.) + ## First-time setup 1. Put your DAT files in `data/dats/`: diff --git a/runner/Dockerfile b/runner/Dockerfile new file mode 100644 index 0000000..396acb8 --- /dev/null +++ b/runner/Dockerfile @@ -0,0 +1,52 @@ +# Wine-based Gitea Actions runner: builds Windows binaries on a Linux host. +# +# Jobs run in "host" mode inside this container, where a Windows CPython 3.12 +# (running under Wine) plus PyInstaller produce the .exe. Node.js and git are +# included so the stock JS actions (actions/checkout, actions/upload-artifact) +# work as-is. +FROM debian:bookworm-slim + +ENV DEBIAN_FRONTEND=noninteractive \ + WINEPREFIX=/root/.wine \ + WINEDEBUG=-all \ + WINEDLLOVERRIDES="mscoree,mshtml=" \ + PYTHON_VERSION=3.12.8 + +# Wine (64-bit), node + git for JS actions, and build/package tooling. +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates curl wget unzip zip \ + wine wine64 xvfb winetricks cabextract \ + nodejs git \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Gitea Actions runner (linux-amd64 binary). +RUN wget -qO /usr/local/bin/act_runner \ + "https://gitea.com/gitea/act_runner/releases/download/v0.6.1/act_runner-0.6.1-linux-amd64" \ + && chmod +x /usr/local/bin/act_runner + +# Windows CPython 3.12, silent install into C:\Python312. +RUN wget -qO /tmp/python-installer.exe \ + "https://www.python.org/ftp/python/${PYTHON_VERSION}/python-${PYTHON_VERSION}-amd64.exe" \ + && xvfb-run -a wine /tmp/python-installer.exe \ + /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_launcher=0 Shortcuts=0 \ + && rm -f /tmp/python-installer.exe \ + && wine "C:\\Python312\\python.exe" --version + +# MSVC runtime required by PySide6's Qt DLLs. +RUN xvfb-run -a winetricks --unattended vcrun2022 + +# Convenience wrapper: winpython -> wine C:\Python312\python.exe +RUN printf '#!/bin/sh\nexec wine "C:\\Python312\\python.exe" "$@"\n' > /usr/local/bin/winpython \ + && chmod +x /usr/local/bin/winpython + +# Pre-install the Windows build deps so CI jobs start fast. +COPY requirements-build.txt /tmp/requirements-build.txt +RUN winpython -m pip install --upgrade pip \ + && winpython -m pip install -r /tmp/requirements-build.txt \ + && rm -f /tmp/requirements-build.txt + +COPY runner/entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +WORKDIR /data +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/runner/entrypoint.sh b/runner/entrypoint.sh new file mode 100644 index 0000000..a8558fc --- /dev/null +++ b/runner/entrypoint.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +# Register on first run, then run the daemon (host mode). +if [ ! -f /data/.runner ]; then + echo "Registering Wine runner with Gitea…" + act_runner register --no-interactive \ + --instance "${GITEA_INSTANCE_URL:?GITEA_INSTANCE_URL is required}" \ + --token "${GITEA_RUNNER_REGISTRATION_TOKEN:?GITEA_RUNNER_REGISTRATION_TOKEN is required}" \ + --name "${RUNNER_NAME:-windows-builder}" \ + --labels "${RUNNER_LABELS:-windows:host}" +fi + +exec act_runner daemon