Files
zoitechat/.github/workflows/windows-build.yml
2026-02-01 18:51:09 -07:00

274 lines
12 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Windows Build
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
windows_build:
runs-on: windows-2019
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 (GTK3 toolchain + packagers)
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
$ErrorActionPreference = "Stop"
New-Item -Name "deps" -ItemType "Directory" -Force | Out-Null
# Inno Setup + IDP (kept as-is)
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
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
# WinSparkle / gendef / perl (kept as-is)
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 | Out-Null
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 | Out-Null
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 }} | Out-Null
# ------------------------------------------
# GTK: Prefer wingtk/gvsbuild GTK3 bundles.
# If x86 GTK3 asset is not published, fall back to legacy bundle for win32 to keep builds working.
# ------------------------------------------
$wantArch = if ("${{ matrix.platform }}" -eq "x64") { "x64" } else { "x86" }
$wantPlat = "${{ matrix.platform }}"
$extractRoot = "C:\_gtk_extract"
if (Test-Path $extractRoot) { Remove-Item $extractRoot -Recurse -Force }
New-Item -Path $extractRoot -ItemType Directory -Force | Out-Null
$gtkPrefix = $null
$headers = @{
"User-Agent" = "zoitechat-ci"
"Authorization" = "Bearer $env:GITHUB_TOKEN"
"X-GitHub-Api-Version" = "2022-11-28"
}
try {
$release = Invoke-RestMethod -Headers $headers -Uri "https://api.github.com/repos/wingtk/gvsbuild/releases/latest"
# Expect names like: GTK3_Gvsbuild_2026.1.0_x64.zip (your log shows this style)
$asset = $release.assets |
Where-Object { $_.name -match '^GTK3_Gvsbuild_.*_(x64|x86)\.zip$' -and $_.name -match "_$wantArch\.zip$" } |
Select-Object -First 1
if (-not $asset) {
if ($wantArch -eq "x86") {
Write-Host "No GTK3 x86 asset found in wingtk/gvsbuild latest release. Falling back to legacy bundle for win32."
} else {
Write-Host "Available assets:"
$release.assets | ForEach-Object { Write-Host " - $($_.name)" }
throw "Could not find a GTK3 $wantArch release asset in wingtk/gvsbuild latest release."
}
}
if ($asset) {
$bundlePath = "deps\gtk3-$wantArch-bundle.zip"
Invoke-WebRequest $asset.browser_download_url -OutFile $bundlePath
Expand-Archive -Force $bundlePath -DestinationPath $extractRoot
# Find prefix by locating gtk.h under include\gtk-3.0\gtk\gtk.h
$candidates = Get-ChildItem -Path $extractRoot -Recurse -File -Filter "gtk.h" |
Where-Object { $_.FullName -match '\\include\\gtk-3\.0\\gtk\\gtk\.h$' }
# Prefer arch-looking paths if present
$header = $candidates | Where-Object { $_.FullName -match "\\$wantArch\\release\\include\\gtk-3\.0\\gtk\\gtk\.h$" } | Select-Object -First 1
if (-not $header) { $header = $candidates | Select-Object -First 1 }
if (-not $header) { throw "GTK3 bundle extracted, but gtk.h not found. Layout unexpected." }
$gtkPrefix = $header.Directory.Parent.Parent.Parent.FullName # ...\include\gtk-3.0\gtk\gtk.h -> prefix = 3 parents up
if (-not (Test-Path (Join-Path $gtkPrefix "bin"))) { throw "GTK3 prefix located, but missing bin/. Layout unexpected: $gtkPrefix" }
if (-not (Test-Path (Join-Path $gtkPrefix "lib"))) { throw "GTK3 prefix located, but missing lib/. Layout unexpected: $gtkPrefix" }
}
} catch {
if ($wantArch -eq "x86") {
Write-Host "Wingtk GTK3 discovery failed for x86. Using legacy GTK bundle for win32."
} else {
throw
}
}
if (-not $gtkPrefix) {
# Legacy bundle path (your original, GTK2-era) to preserve win32 builds
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk | Out-Null
} else {
# Normalize GTK location to the path your solution already expects:
# C:\gtk-build\gtk\<platform>\release\...
$normBase = "C:\gtk-build\gtk\$wantPlat"
New-Item -Path $normBase -ItemType Directory -Force | Out-Null
$normRel = Join-Path $normBase "release"
if (Test-Path $normRel) {
cmd /c rmdir /s /q "$normRel" | Out-Null
}
New-Item -Path $normRel -ItemType Junction -Value $gtkPrefix | Out-Null
$gtkBin = Join-Path $normRel "bin"
$gtkLib = Join-Path $normRel "lib"
$gtkInc = Join-Path $normRel "include"
# glib-genmarshal: vcxproj calls python.exe <path>\glib-genmarshal (no extension)
# Make a python wrapper named "glib-genmarshal" that dispatches to the real tool.
$genExe = Get-ChildItem -Path $gtkBin -File -Filter "glib-genmarshal*.exe" | Select-Object -First 1
if (-not $genExe) { throw "GTK3 bundle extracted, but glib-genmarshal.exe not found under $gtkBin." }
$genTarget = Join-Path $gtkBin "glib-genmarshal"
$wrapper = @(
"import os, subprocess, sys",
"tool = os.path.join(os.path.dirname(__file__), `"$($genExe.Name)`")",
"sys.exit(subprocess.call([tool] + sys.argv[1:]))"
)
$wrapper | Set-Content -Path $genTarget -Encoding ASCII
# Compatibility aliases (dont explode if naming differs)
function Copy-AliasLib([string]$targetName, [string[]]$sourcePatterns) {
$target = Join-Path $gtkLib $targetName
if (Test-Path $target) { return }
$src = $null
foreach ($pat in $sourcePatterns) {
$src = Get-ChildItem -Path $gtkLib -File -Filter "*.lib" | Where-Object { $_.Name -match $pat } | Select-Object -First 1
if ($src) { break }
}
if ($src) {
Copy-Item $src.FullName $target -Force
Write-Host "Alias: $targetName <= $($src.Name)"
} else {
Write-Host "Alias not created: $targetName (no match in $gtkLib)"
}
}
# GTK2 name expected by older vcxproj
Copy-AliasLib "gtk-win32-2.0.lib" @(
'^gtk-3\.0\.lib$',
'^gtk-3-0\.lib$',
'^gtk-3\.lib$',
'^gtk-3.*\.lib$'
)
# OpenSSL legacy names
Copy-AliasLib "ssleay32.lib" @('^libssl\.lib$', '^ssl\.lib$')
Copy-AliasLib "libeay32.lib" @('^libcrypto\.lib$', '^crypto\.lib$')
# libxml2 legacy name
Copy-AliasLib "libxml2.lib" @('^libxml2.*\.lib$')
# Lua headers: if luajit headers exist, copy them to include\ so <lua.h> works
$luajitDir = Join-Path $gtkInc "luajit-2.1"
if (Test-Path $luajitDir) {
foreach ($h in @("lua.h", "lualib.h", "lauxlib.h", "luaconf.h")) {
$src = Join-Path $luajitDir $h
if (Test-Path $src) {
Copy-Item $src (Join-Path $gtkInc $h) -Force
}
}
}
}
# 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
- name: Build
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\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 }}
shell: cmd
- name: Preparing Artifacts
run: |
move ..\zoitechat-build\${{ matrix.platform }}\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 }}