Files
zoitechat/.github/workflows/windows-build.yml
deepend 874ea99492 win32/copy/copy.vcxproj
Switched hardcoded DLL names to wildcard patterns (ex: atk-1.0-0.dll → *atk-1.0-0.dll, iconv.dll → *iconv*.dll, etc.) so it correctly picks up lib* prefixed builds.
  Made Enchant provider copying resilient by copying lib\enchant\*.dll instead of a single hardcoded libenchant_myspell.dll.
  Added optional copy support for LuaJIT DLLs (luajit*.dll) alongside lua51.dll.

win32/installer/zoitechat.iss.tt
  Updated DLL Source: entries to match real-world names from dependency bundles using wildcards (*glib-2*.dll, *gtk-3*.dll, etc.).
  Added optional LuaJIT inclusion (skip if missing) and wildcarded girepository.

win32/zoitechat.props
  Added env overrides so CI (and humans) can actually control paths:
  ZOITECHAT_DEPS_PATH
  ZOITECHAT_PYTHON3_PATH
  already supported ISCC_EXE and now it actually matters.
  Fixed glib-genmarshal handling to prefer glib-genmarshal.exe if present (and only use Python script path if needed).
  Added library-name auto-detection for MSVC import libs (gtk-3.lib vs gtk-3.0.lib vs libgtk-3.lib, etc.) so linking doesn’t die just because the bundle names differ.
  Ensured InstallerEnabled gets re-evaluated after IsccPath is resolved (GTK3 had the order wrong, so installer builds could be silently disabled).

.github/workflows/windows-build.yml
  Made artifact collection and plugin validation tolerate win32 vs Win32 output directory naming, instead of assuming humans are consistent (they aren’t).
2026-02-14 15:57:41 -07:00

275 lines
11 KiB
YAML

name: Windows Build
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
windows_build:
runs-on: windows-2022
permissions:
contents: read
id-token: write
attestations: write
artifact-metadata: write
strategy:
matrix:
platform: [x64, win32]
arch: [x64, x86]
exclude:
- platform: x64
arch: x86
- platform: win32
arch: x64
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.14.2'
architecture: ${{ matrix.arch }}
- name: Install Dependencies
run: |
New-Item -Name "deps" -ItemType "Directory"
New-Item -Path "C:\gtk-build" -ItemType "Directory" -Force | Out-Null
Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe
& deps\innosetup-unicode.exe /VERYSILENT | Out-Null
$isccCandidates = @(
(Join-Path ${env:ProgramFiles(x86)} 'Inno Setup 5\iscc.exe'),
(Join-Path ${env:ProgramFiles(x86)} 'Inno Setup 6\iscc.exe'),
(Join-Path $env:ProgramFiles 'Inno Setup 5\iscc.exe'),
(Join-Path $env:ProgramFiles 'Inno Setup 6\iscc.exe')
) | Where-Object { $_ -and (Test-Path $_) }
$isccPath = $isccCandidates | Select-Object -First 1
if (-not $isccPath) {
$isccCmd = Get-Command iscc.exe -ErrorAction SilentlyContinue
if ($isccCmd) { $isccPath = $isccCmd.Source }
}
if (-not $isccPath) {
throw 'Inno Setup compiler (iscc.exe) not found after installer step.'
}
"ISCC_EXE=$isccPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe
& deps\idpsetup.exe /VERYSILENT
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z
& 7z.exe x deps\gendef.7z -oC:\gtk-build
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z
& 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z
& 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }}
# Resolve python root from setup-python
$pyRoot = $env:pythonLocation
if (-not $pyRoot) { $pyRoot = & python -c "import sys; print(sys.prefix)" }
# Create BOTH paths because the .vcxproj hard-codes python-3.14\...
foreach ($pyDir in @("C:\gtk-build\python-3.14.2", "C:\gtk-build\python-3.14")) {
New-Item -Path $pyDir -ItemType Directory -Force | Out-Null
$target = Join-Path $pyDir "${{ matrix.platform }}"
if (Test-Path $target) { Remove-Item $target -Recurse -Force }
New-Item -Path $pyDir -Name "${{ matrix.platform }}" -ItemType Junction -Value $pyRoot | Out-Null
}
python -m pip install --upgrade pip
python -m pip install cffi
$gtkArchive = "GTK3_Gvsbuild_zoitechat-2.18.0-pre1_${{ matrix.arch }}.7z"
Invoke-WebRequest "https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre1/$gtkArchive" -OutFile deps\gtk.7z
if ("${{ matrix.platform }}" -eq "x64") {
& 7z.exe x deps\gtk.7z -oC:\gtk-build\gtk\x64\release
} else {
& 7z.exe x deps\gtk.7z -oC:\gtk-build\gtk\x86\release
}
if ($LASTEXITCODE -gt 1) {
throw "gtk.7z extraction failed with exit code $LASTEXITCODE"
}
if ("${{ matrix.platform }}" -eq "win32" -and (Test-Path "C:\gtk-build\gtk\x86")) {
$gtkRoot = "C:\gtk-build\gtk"
foreach ($alias in @("Win32", "win32")) {
$aliasPath = Join-Path $gtkRoot $alias
if (-not (Test-Path $aliasPath)) {
New-Item -Path $aliasPath -ItemType Junction -Value (Join-Path $gtkRoot "x86") | Out-Null
}
}
}
- name: Install Lua Dependencies
run: |
$releaseArch = if ("${{ matrix.arch }}" -eq "x64") { "x64" } else { "x86" }
$gtkRelease = "C:\gtk-build\gtk\$releaseArch\release"
if (-not (Test-Path $gtkRelease)) {
throw "GTK release root '$gtkRelease' is missing before Lua dependency extraction."
}
$luaArchive = if ($releaseArch -eq "x64") { "gtk-x64-2018-08-29-openssl1.1.7z" } else { "gtk-win32-2018-08-29-openssl1.1.7z" }
$luaArchivePath = "deps\$luaArchive"
Invoke-WebRequest "https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/$luaArchive" -OutFile $luaArchivePath
& 7z.exe x $luaArchivePath -o$gtkRelease include\luajit*\* include\lua*\* lib\lua51.lib lib\luajit*.lib bin\lua51.dll bin\luajit*.dll lib\lua\2.1\* lib\girepository-1.0\*.typelib share\lua\2.1\* -r
if ($LASTEXITCODE -gt 1) {
throw "Lua dependency extraction failed with exit code $LASTEXITCODE"
}
- name: Validate Lua Prerequisites
run: |
$releaseArch = if ("${{ matrix.arch }}" -eq "x64") { "x64" } else { "x86" }
$gtkRelease = "C:\gtk-build\gtk\$releaseArch\release"
$includeCandidates = @(
"include\luajit-2.1\lua.h",
"include\luajit\lua.h",
"include\lua5.1\lua.h",
"include\lua51\lua.h"
)
$libCandidates = @(
"lib\lua51.lib",
"lib\luajit-5.1.lib",
"lib\luajit.lib"
)
$dllCandidates = @(
"bin\lua51.dll",
"bin\luajit-5.1.dll",
"bin\luajit.dll"
)
function Test-AnyPath([string]$root, [string[]]$candidates) {
foreach ($candidate in $candidates) {
if (Test-Path (Join-Path $root $candidate)) {
return $true
}
}
return $false
}
$missing = New-Object System.Collections.Generic.List[string]
if (-not (Test-AnyPath $gtkRelease $includeCandidates)) {
$missing.Add("include (expected one of: $($includeCandidates -join ', '))")
}
if (-not (Test-AnyPath $gtkRelease $libCandidates)) {
$missing.Add("lib import library (expected one of: $($libCandidates -join ', '))")
}
if (-not (Test-AnyPath $gtkRelease $dllCandidates)) {
$missing.Add("bin runtime DLL (expected one of: $($dllCandidates -join ', '))")
}
$lgiNative = Join-Path $gtkRelease "lib\lua\2.1\lgi"
if (-not (Test-Path $lgiNative) -or -not (Get-ChildItem $lgiNative -Filter *.dll -File -ErrorAction SilentlyContinue)) {
$missing.Add("lib\\lua\\2.1\\lgi\\*.dll")
}
$typelibDir = Join-Path $gtkRelease "lib\girepository-1.0"
if (-not (Test-Path $typelibDir) -or -not (Get-ChildItem $typelibDir -Filter *.typelib -File -ErrorAction SilentlyContinue)) {
$missing.Add("lib\\girepository-1.0\\*.typelib")
}
$lgiShare = Join-Path $gtkRelease "share\lua\2.1\lgi"
if (-not (Test-Path $lgiShare) -or -not (Get-ChildItem $lgiShare -Filter *.lua -File -Recurse -ErrorAction SilentlyContinue)) {
$missing.Add("share\\lua\\2.1\\lgi\\*.lua")
}
if ($missing.Count -gt 0) {
Write-Error "Lua prerequisites are missing under '$gtkRelease': $($missing -join '; '). Ensure the Lua/LuaJIT dependency artifact for $releaseArch was downloaded and extracted."
exit 1
}
"LUA_PREREQ_ROOT=$gtkRelease" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Build
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
set "PYTHON_DIR=C:\gtk-build\python-3.14.2\${{ matrix.platform }}"
if not exist "%PYTHON_DIR%\libs\python314.lib" (
echo Missing %PYTHON_DIR%\libs\python314.lib
dir "%PYTHON_DIR%\libs"
exit /b 1
)
set "LIB=%PYTHON_DIR%\libs;%LIB%"
set "INCLUDE=%PYTHON_DIR%\include;%INCLUDE%"
msbuild win32\zoitechat.sln /m /verbosity:minimal /p:Configuration=Release /p:Platform=${{ matrix.platform }}
set "BUILD_DIR=..\zoitechat-build\${{ matrix.platform }}"
if not exist "%BUILD_DIR%" if /I "${{ matrix.platform }}"=="win32" set "BUILD_DIR=..\zoitechat-build\Win32"
if not exist "%BUILD_DIR%" if /I "${{ matrix.platform }}"=="win32" set "BUILD_DIR=..\zoitechat-build\WIN32"
set "PLUGIN_DIR=%BUILD_DIR%\rel\plugins"
for %%F in (hcchecksum.dll hcexec.dll hcfishlim.dll hcsysinfo.dll hcupd.dll hcwinamp.dll hcperl.dll hcpython3.dll hclua.dll) do (
if not exist "%PLUGIN_DIR%\%%F" (
if /I "%%F"=="hclua.dll" (
echo Missing expected plugin: %PLUGIN_DIR%\%%F
echo hclua.dll is built from Lua/LuaJIT prerequisites under %LUA_PREREQ_ROOT%.
echo Verify include/lib/bin/share Lua files were present during dependency validation.
) else (
echo Missing expected plugin: %PLUGIN_DIR%\%%F
)
exit /b 1
)
)
shell: cmd
- name: Preparing Artifacts
run: |
set "BUILD_DIR=..\zoitechat-build\${{ matrix.platform }}"
if not exist "%BUILD_DIR%" if /I "${{ matrix.platform }}"=="win32" set "BUILD_DIR=..\zoitechat-build\Win32"
if not exist "%BUILD_DIR%" if /I "${{ matrix.platform }}"=="win32" set "BUILD_DIR=..\zoitechat-build\WIN32"
if not exist "%BUILD_DIR%" (
echo Missing build output dir: %BUILD_DIR%
dir ..\zoitechat-build
exit /b 1
)
move "%BUILD_DIR%\ZoiteChat*.exe" .\
move ..\zoitechat-build .\
shell: cmd
- name: Upload Installer
id: upload_installer
uses: actions/upload-artifact@v4
with:
name: Installer ${{ matrix.arch }}
path: ZoiteChat*.exe
- name: Attest Installer (Artifact Attestation)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: actions/attest-build-provenance@v3
with:
subject-name: Installer ${{ matrix.arch }}
subject-digest: sha256:${{ steps.upload_installer.outputs.artifact-digest }}
- name: Upload Build Files
id: upload_buildfiles
uses: actions/upload-artifact@v4
with:
name: Build Files ${{ matrix.arch }}
path: zoitechat-build
- name: Attest Build Files (Artifact Attestation)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: actions/attest-build-provenance@v3
with:
subject-name: Build Files ${{ matrix.arch }}
subject-digest: sha256:${{ steps.upload_buildfiles.outputs.artifact-digest }}