Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: Build Release Installer
run-name: Build LTOG ${{ inputs.version }} installer

on:
workflow_dispatch:
inputs:
version:
description: 'Release version, for example 1.0.0'
required: true
type: string

permissions:
contents: write

jobs:
build-release:
name: Build and publish installer
runs-on: windows-latest

env:
WINFSP_MSI_URL: https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi
WINFSP_MSI_SHA256: 073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A

steps:
- name: Validate version
shell: pwsh
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
$version = $env:INPUT_VERSION
if ($version -notmatch '^\d+\.\d+\.\d+(\.\d+)?$') {
throw "Version must look like 1.0.0 or 1.0.0.0. Got '$version'."
}
"RELEASE_VERSION=$version" >> $env:GITHUB_ENV
"RELEASE_TAG=v$version" >> $env:GITHUB_ENV

- name: Configure Git line endings
shell: pwsh
run: git config --global core.autocrlf input

- name: Check out repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'

- name: Set up MSYS2
id: msys2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
git
autoconf
automake
libtool
make
pkgconf
mingw-w64-x86_64-toolchain
mingw-w64-x86_64-libxml2
mingw-w64-x86_64-icu
mingw-w64-x86_64-pkgconf

- name: Extract WinFsp developer files
shell: pwsh
run: |
$msi = Join-Path $env:RUNNER_TEMP 'winfsp.msi'
Invoke-WebRequest -Uri $env:WINFSP_MSI_URL -OutFile $msi
$actual = (Get-FileHash $msi -Algorithm SHA256).Hash
if ($actual -ne $env:WINFSP_MSI_SHA256) {
throw "WinFsp MSI SHA256 mismatch: got $actual, expected $env:WINFSP_MSI_SHA256"
}

$extractRoot = Join-Path $env:RUNNER_TEMP 'winfsp'
New-Item -ItemType Directory -Force -Path $extractRoot | Out-Null
$msiArgs = @(
'/a', "`"$msi`"",
"TARGETDIR=`"$extractRoot`"",
'/qn',
'/norestart'
)
$process = Start-Process msiexec.exe -Wait -PassThru -ArgumentList $msiArgs
if ($process.ExitCode -ne 0) {
throw "WinFsp MSI extraction failed with exit code $($process.ExitCode)."
}

$winfspRoot = Join-Path $extractRoot 'DYNAMIC'
$lib = Join-Path $winfspRoot 'lib\winfsp-x64.lib'
$dll = Join-Path $winfspRoot 'SxS\DYNAMIC\bin\winfsp-x64.dll'
if (-not (Test-Path $lib)) {
throw "WinFsp MSI extraction did not produce '$lib'."
}
if (-not (Test-Path $dll)) {
throw "WinFsp MSI extraction did not produce '$dll'."
}
New-Item -ItemType Directory -Force -Path (Join-Path $winfspRoot 'bin') | Out-Null
Copy-Item $dll (Join-Path $winfspRoot 'bin\winfsp-x64.dll') -Force
"WINFSP=$winfspRoot" >> $env:GITHUB_ENV

- name: Build installer
shell: pwsh
env:
MSYS2_ROOT: ${{ steps.msys2.outputs['msys2-location'] }}
run: pwsh -NoProfile -ExecutionPolicy Bypass -File .\build.ps1 -Version $env:RELEASE_VERSION -Msys2Root $env:MSYS2_ROOT

- name: Locate installer
id: installer
shell: pwsh
run: |
$installer = Get-ChildItem .\installer\Output -Filter "LTOG-$env:RELEASE_VERSION-setup.exe" |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1
if (-not $installer) {
throw "Installer not found in installer\Output."
}
"path=$($installer.FullName)" >> $env:GITHUB_OUTPUT

- name: Create GitHub Release
shell: pwsh
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create $env:RELEASE_TAG "${{ steps.installer.outputs.path }}" `
--target "${{ github.sha }}" `
--title "LTOG $env:RELEASE_VERSION" `
--notes "Installer build for LTOG $env:RELEASE_VERSION." `
--latest
14 changes: 11 additions & 3 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
.PARAMETER Msys2Root
Path to the MSYS2 installation. Default: C:\msys64.

.PARAMETER Version
Version embedded into the GUI assembly and installer. Default: 1.0.0.

.EXAMPLE
pwsh -File build.ps1 # full clean build of everything

Expand All @@ -40,7 +43,9 @@
param(
[switch]$SkipNative,
[switch]$NoInstaller,
[string]$Msys2Root = 'C:\msys64'
[string]$Msys2Root = 'C:\msys64',
[ValidatePattern('^\d+\.\d+\.\d+(\.\d+)?$')]
[string]$Version = '1.0.0'
)

Set-StrictMode -Version Latest
Expand Down Expand Up @@ -132,9 +137,12 @@ Step 'Building self-contained WinUI 3 GUI (dotnet)'
if (-not (Get-Command dotnet -ErrorAction SilentlyContinue)) {
throw "dotnet not found. Install the .NET 8 SDK (winget install Microsoft.DotNet.SDK.8)."
}
$assemblyVersion = if (($Version.Split('.')).Count -eq 3) { "$Version.0" } else { $Version }
Push-Location $GuiDir
try {
& dotnet build 'LTOG.Gui.csproj' -c Release -p:Platform=x64 --nologo
& dotnet build 'LTOG.Gui.csproj' -c Release -p:Platform=x64 `
-p:Version=$Version -p:AssemblyVersion=$assemblyVersion -p:FileVersion=$assemblyVersion `
--nologo
if ($LASTEXITCODE -ne 0) { throw "dotnet build failed (exit $LASTEXITCODE)." }
} finally {
Pop-Location
Expand All @@ -154,7 +162,7 @@ if ($NoInstaller) {
} else {
Step 'Building Windows installer'
& pwsh -NoProfile -ExecutionPolicy Bypass `
-File (Join-Path $InstallerDir 'build-installer.ps1') -AutoInstallInnoSetup
-File (Join-Path $InstallerDir 'build-installer.ps1') -AutoInstallInnoSetup -Version $Version
if ($LASTEXITCODE -ne 0) { throw "installer build failed (exit $LASTEXITCODE)." }
}

Expand Down
2 changes: 2 additions & 0 deletions installer/LTOG.iss
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
; ===========================================================================

#define MyAppName "LTOG"
#ifndef MyAppVersion
#define MyAppVersion "1.0.0"
#endif
#define MyAppId "{6E9D2B4A-1C3F-4E58-9A7D-2F5B8C1E4D0A}"
#define MyAppPublisher "rlaphoenix"
#define MyAppURL "https://github.com/rlaphoenix/LTOG"
Expand Down
11 changes: 9 additions & 2 deletions installer/build-installer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@

.EXAMPLE
pwsh -ExecutionPolicy Bypass -File .\build-installer.ps1

.PARAMETER Version
Version embedded into the installer metadata and output filename. Default: 1.0.0.
#>
[CmdletBinding()]
param(
# Compile even if ISCC has to be installed via winget without prompting.
[switch]$AutoInstallInnoSetup
[switch]$AutoInstallInnoSetup,

# Installer/application version. Passed through to LTOG.iss.
[ValidatePattern('^\d+\.\d+\.\d+(\.\d+)?$')]
[string]$Version = '1.0.0'
)

Set-StrictMode -Version Latest
Expand Down Expand Up @@ -131,7 +138,7 @@ Write-Host " using $iscc"

# --- 4. compile -----------------------------------------------------------
Write-Step 'Compiling installer'
& $iscc $IssFile
& $iscc "/DMyAppVersion=$Version" $IssFile
if ($LASTEXITCODE -ne 0) { throw "ISCC failed with exit code $LASTEXITCODE." }

$out = Get-ChildItem (Join-Path $Root 'Output') -Filter '*.exe' |
Expand Down