Build the Windows installer in CI
The fourth leg of build-and-test.yml, in the shape of the Android one: an image workflow that builds docker/windows and pushes it tagged by the directory's tree id, and a job inside that image that lints the Windows target — the only place the cfg(windows) branches are ever compiled by CI — builds, runs the smoke tests docs/windows.md §6 specifies, packages, installs and uninstalls under Wine, and uploads the installer. Every step was run by hand in the same container first. The spec's open list closes with this: the four §3.2 items, the licence page, and the leg. What remains is what Wine cannot show, and §10 now lists it as the first real Windows run's checklist.
This commit is contained in:
@@ -365,6 +365,112 @@ jobs:
|
||||
path: target-android/apk/darkroom.apk
|
||||
if-no-files-found: error
|
||||
|
||||
windows-image:
|
||||
uses: ./.gitea/workflows/windows-image.yml
|
||||
|
||||
# TRACES: FR-PLAT-WIN-3
|
||||
# The Windows executable and its installer, cross-built from Linux
|
||||
# (docs/windows.md §7). No Windows machine anywhere in this job: what it
|
||||
# can prove is that the binary links, is a Windows executable with no
|
||||
# MinGW runtime imports, starts under Wine, and that the installer installs
|
||||
# and uninstalls under Wine. What it cannot prove — a Vulkan device, a
|
||||
# render, the secret store — is a release step on a real machine (§6).
|
||||
windows:
|
||||
runs-on: linux/amd64
|
||||
name: Windows (x86_64, cross)
|
||||
needs: windows-image
|
||||
container:
|
||||
image: gitea.tourolle.paris/dtourolle/darkroom-windows:latest
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
CARGO_PROFILE_DEV_DEBUG: 0
|
||||
CARGO_TARGET_DIR: target-windows
|
||||
# Wine keeps its prefix under $HOME, which the image points at a
|
||||
# directory that does not exist in a fresh container.
|
||||
HOME: /tmp/home
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Same step as the desktop leg: the models are LFS objects and the
|
||||
# packager refuses pointers.
|
||||
- name: Fetch the models
|
||||
env:
|
||||
LFS_TOKEN: ${{ secrets.GITEA_TOKEN || github.token }}
|
||||
run: |
|
||||
set -e
|
||||
git lfs install --local
|
||||
git config --local --get-regexp '^http\..*extraheader$' \
|
||||
| cut -d' ' -f1 | sort -u \
|
||||
| while read -r key; do git config --local --unset-all "$key"; done || true
|
||||
git config --local lfs.url \
|
||||
"https://x-access-token:${LFS_TOKEN}@gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs"
|
||||
git lfs pull
|
||||
ls -l models/face models/scene
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
/opt/cargo/registry
|
||||
target-windows
|
||||
key: windows-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# The cfg(windows) branches are linted here and nowhere else: the
|
||||
# desktop leg's clippy never compiles them.
|
||||
- name: Clippy for the target
|
||||
run: cargo clippy --release --target x86_64-pc-windows-gnu -p darkroom-desktop -- -D warnings
|
||||
|
||||
- name: Build
|
||||
run: cargo build --release --target x86_64-pc-windows-gnu -p darkroom-desktop
|
||||
|
||||
- name: Smoke-test the executable
|
||||
run: |
|
||||
set -e
|
||||
mkdir -p "$HOME"
|
||||
EXE=target-windows/x86_64-pc-windows-gnu/release/darkroom-desktop.exe
|
||||
file "$EXE"
|
||||
file "$EXE" | grep -q 'PE32+' || { echo "FAIL: not a PE32+ executable"; exit 1; }
|
||||
file "$EXE" | grep -q '(GUI)' || { echo "FAIL: not a GUI-subsystem executable"; exit 1; }
|
||||
if x86_64-w64-mingw32-objdump -p "$EXE" | grep -iE 'libwinpthread|libgcc|libstdc'; then
|
||||
echo "FAIL: the executable imports a MinGW runtime DLL"
|
||||
exit 1
|
||||
fi
|
||||
x86_64-w64-mingw32-objdump -p "$EXE" | grep 'DLL Name' | sort -u
|
||||
wineboot --init >/dev/null 2>&1 || true
|
||||
OUT=$(wine "$EXE" --version 2>/dev/null)
|
||||
echo "wine: $OUT"
|
||||
echo "$OUT" | grep -q '^darkroom-desktop ' || { echo "FAIL: --version did not answer under Wine"; exit 1; }
|
||||
|
||||
- name: Package the installer
|
||||
run: bash docker/windows/package.sh
|
||||
|
||||
- name: Smoke-test the installer
|
||||
run: |
|
||||
set -e
|
||||
SETUP=$(ls target-windows/installer/DarkRoom-*-x86_64-setup.exe)
|
||||
file "$SETUP" | grep -q 'PE32+' || { echo "FAIL: the installer is not 64-bit"; exit 1; }
|
||||
wine "$SETUP" /S 2>/dev/null
|
||||
INST=$(echo "$HOME"/.wine/drive_c/users/*/AppData/Local/Programs/DarkRoom)
|
||||
ls "$INST"
|
||||
[ "$(ls "$INST/models" | wc -l)" = 7 ] || { echo "FAIL: expected 7 model files"; exit 1; }
|
||||
wine reg query 'HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\DarkRoom' 2>/dev/null \
|
||||
| grep -q DisplayVersion || { echo "FAIL: no uninstall registry key"; exit 1; }
|
||||
wine "$INST/darkroom.exe" --version 2>/dev/null | grep -q '^darkroom-desktop ' \
|
||||
|| { echo "FAIL: the installed executable does not run"; exit 1; }
|
||||
wine "$INST/uninstall.exe" /S 2>/dev/null
|
||||
sleep 3
|
||||
[ ! -e "$INST" ] || { echo "FAIL: uninstall left $INST behind"; ls -R "$INST"; exit 1; }
|
||||
echo "OK: installed and uninstalled under Wine"
|
||||
|
||||
- name: Upload the installer
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: darkroom-windows-x86_64-setup
|
||||
path: target-windows/installer/DarkRoom-*-x86_64-setup.exe
|
||||
if-no-files-found: error
|
||||
|
||||
layering:
|
||||
runs-on: linux/amd64
|
||||
name: Layer separation
|
||||
|
||||
Reference in New Issue
Block a user