mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-10-05 02:37:24 -04:00
The four dotnet publish calls share one run: block, and on windows-latest that block is pwsh. PowerShell does not stop at a native command that fails, and the step is judged by $LASTEXITCODE after the whole block, so only the last publish was ever able to fail the build. That is not hypothetical. LibationWinForms stopped compiling and every run since stayed green: the WinForms publish errored, the three after it succeeded, the step exited 0, and the job uploaded a Libation-Classic zip containing Hangover and the CLI but no Libation.exe at all. upload-artifact's if-no-files-found did not help, since the zip itself was there. Check the exit code after each publish, and refuse to package output with no Libation.exe in it - both UIs build under that name. Linux and macOS are not affected; their steps are bash, which Actions runs with -e. Co-authored-by: rmcrackan <rmcrackan@gmail.com>
146 lines
5.3 KiB
YAML
146 lines
5.3 KiB
YAML
# build-windows.yml
|
|
# Reusable workflow that builds the Windows versions of Libation.
|
|
---
|
|
name: build
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
libation-version:
|
|
type: string
|
|
required: true
|
|
dotnet-version:
|
|
type: string
|
|
required: true
|
|
run-unit-tests:
|
|
type: boolean
|
|
publish-r2r:
|
|
type: boolean
|
|
build-installer:
|
|
type: boolean
|
|
description: "Build *-setup.exe on all Windows matrix jobs when release (zips always built for .releaseindex.json)"
|
|
default: false
|
|
retention-days:
|
|
type: number
|
|
|
|
jobs:
|
|
build:
|
|
name: "Windows-${{ matrix.release_name }}-${{ matrix.architecture }} (${{ matrix.ui }})"
|
|
runs-on: windows-latest
|
|
strategy:
|
|
matrix:
|
|
ui: [Avalonia]
|
|
architecture: [x64]
|
|
release_name: [chardonnay]
|
|
artifact_stem: [Libation]
|
|
include:
|
|
- architecture: x64
|
|
ui: WinForms
|
|
release_name: classic
|
|
artifact_stem: Libation-Classic
|
|
- architecture: arm64
|
|
ui: Avalonia
|
|
release_name: chardonnay
|
|
artifact_stem: Libation
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- uses: actions/setup-dotnet@v6
|
|
with:
|
|
dotnet-version: ${{ inputs.dotnet-version }}
|
|
dotnet-quality: "ga"
|
|
|
|
- name: Unit test
|
|
if: ${{ inputs.run-unit-tests }}
|
|
working-directory: ./Source
|
|
run: dotnet test
|
|
|
|
- name: Publish
|
|
working-directory: ./Source
|
|
run: |
|
|
$PUBLISH_ARGS=@(
|
|
"--runtime", "win-${{ matrix.architecture }}",
|
|
"--configuration", "Release",
|
|
"--output", "../bin",
|
|
"-p:PublishProtocol=FileSystem",
|
|
"-p:PublishReadyToRun=${{ inputs.publish-r2r }}",
|
|
"-p:SelfContained=true")
|
|
|
|
# PowerShell does not stop at a native command that fails, and the step is judged by the exit code
|
|
# of the last one, so a publish that fails anywhere but the end passes as a green build. That is not
|
|
# hypothetical: LibationWinForms failed to compile for a while and every run stayed green, uploading
|
|
# a Libation-Classic zip with no Libation.exe in it. Check each one.
|
|
$projects = @(
|
|
"Libation${{ matrix.ui }}/Libation${{ matrix.ui }}.csproj",
|
|
"LoadByOS/WindowsConfigApp/WindowsConfigApp.csproj",
|
|
"LibationCli/LibationCli.csproj",
|
|
"Hangover${{ matrix.ui }}/Hangover${{ matrix.ui }}.csproj")
|
|
|
|
foreach ($project in $projects) {
|
|
dotnet publish "$project" $PUBLISH_ARGS
|
|
if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed for $project" }
|
|
}
|
|
|
|
- name: Zip artifact
|
|
id: zip
|
|
working-directory: ./bin
|
|
run: |
|
|
$delfiles = @(
|
|
"WindowsConfigApp.exe",
|
|
"WindowsConfigApp.runtimeconfig.json",
|
|
"WindowsConfigApp.deps.json")
|
|
|
|
foreach ($file in $delfiles){ if (test-path $file){ Remove-Item $file } }
|
|
|
|
# Both UIs publish as Libation.exe. upload-artifact's if-no-files-found only proves the zip exists,
|
|
# which it does whether or not the app is inside it, so say outright that it has to be.
|
|
if (-not (Test-Path "Libation.exe")) { throw "Libation.exe is missing from the publish output" }
|
|
|
|
$artifact="${{ matrix.artifact_stem }}.${{ inputs.libation-version }}-windows-${{ matrix.release_name }}-${{ matrix.architecture }}.zip"
|
|
"artifact=$artifact" >> $env:GITHUB_OUTPUT
|
|
Compress-Archive -Path * -DestinationPath "$artifact"
|
|
|
|
- uses: actions/upload-artifact@v7
|
|
with:
|
|
name: ${{ steps.zip.outputs.artifact }}
|
|
path: ./bin/${{ steps.zip.outputs.artifact }}
|
|
if-no-files-found: error
|
|
retention-days: ${{ inputs.retention-days }}
|
|
|
|
- name: Install Inno Setup
|
|
if: ${{ inputs.build-installer }}
|
|
run: choco install innosetup -y --no-progress
|
|
|
|
- name: Build Windows installer
|
|
id: setup
|
|
if: ${{ inputs.build-installer }}
|
|
shell: pwsh
|
|
run: |
|
|
if ("${{ matrix.ui }}" -eq "WinForms") {
|
|
$setupName = "Libation-Classic.${{ inputs.libation-version }}-windows-${{ matrix.release_name }}-${{ matrix.architecture }}-setup.exe"
|
|
$ui = "WinForms"
|
|
} else {
|
|
$setupName = "Libation.${{ inputs.libation-version }}-windows-${{ matrix.release_name }}-${{ matrix.architecture }}-setup.exe"
|
|
$ui = "Avalonia"
|
|
}
|
|
./Scripts/Windows/Build-WindowsInstaller.ps1 `
|
|
-Version "${{ inputs.libation-version }}" `
|
|
-Ui $ui `
|
|
-Architecture "${{ matrix.architecture }}" `
|
|
-SkipPublish `
|
|
-BinDir "${{ github.workspace }}/bin"
|
|
if (-not (Test-Path "${{ github.workspace }}/bin/$setupName")) {
|
|
throw "Installer not found: bin/$setupName"
|
|
}
|
|
"setup=$setupName" >> $env:GITHUB_OUTPUT
|
|
|
|
- name: Upload installer artifact
|
|
if: ${{ inputs.build-installer }}
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: ${{ steps.setup.outputs.setup }}
|
|
path: ./bin/${{ steps.setup.outputs.setup }}
|
|
if-no-files-found: error
|
|
retention-days: ${{ inputs.retention-days }}
|
|
|