build: ship NativeAOT, add Scoop packaging and signing hooks #4
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: AOT trial | |
| # Experiment, not a gate. NativeAOT needs the MSVC linker from the Desktop C++ workload, which the | |
| # GitHub Windows runners have and a typical dev machine may not — so this is where the question | |
| # "does OpenKey build and run AOT-compiled" actually gets answered. | |
| # | |
| # Reports size and startup against the current single-file build so the trade is a measurement | |
| # rather than an argument. See docs/06 and docs/architecture/08-decisions.md. | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [feat/aot-and-distribution] | |
| permissions: | |
| contents: read | |
| jobs: | |
| aot: | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false # arm64 failing must not hide an x64 result, or vice versa | |
| matrix: | |
| rid: [win-x64, win-arm64] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-dotnet@v4 | |
| # Cross-compiling to arm64 needs the ARM64 C++ build tools, which are a separate component | |
| # from the x64 ones. Installing them here rather than finding out during a release. | |
| - name: Ensure ARM64 C++ tools | |
| if: matrix.rid == 'win-arm64' | |
| shell: pwsh | |
| run: | | |
| $vs = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe" | |
| $path = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath | |
| Write-Host "Visual Studio at: $path" | |
| & $vs modify --installPath "$path" --quiet --norestart --nocache ` | |
| --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 | Out-Null | |
| Write-Host "exit: $LASTEXITCODE" | |
| - name: Publish AOT | |
| run: > | |
| dotnet publish src/OpenKey/OpenKey.csproj -c Release -r ${{ matrix.rid }} | |
| -p:PublishAot=true | |
| -p:PublishSingleFile=false | |
| -p:PublishReadyToRun=false | |
| -p:EnableCompressionInSingleFile=false | |
| -o out-aot | |
| - name: Publish the current single-file build for comparison | |
| run: dotnet publish src/OpenKey/OpenKey.csproj -c Release -r ${{ matrix.rid }} -o out-singlefile | |
| - name: Compare | |
| shell: pwsh | |
| run: | | |
| $aot = Get-Item out-aot/OpenKey.exe | |
| $single = Get-Item out-singlefile/OpenKey.exe | |
| $aotMb = [math]::Round($aot.Length / 1MB, 1) | |
| $singleMb = [math]::Round($single.Length / 1MB, 1) | |
| Write-Host "single-file : $singleMb MB" | |
| Write-Host "AOT : $aotMb MB" | |
| Write-Host "delta : $([math]::Round($singleMb - $aotMb, 1)) MB smaller" | |
| # A native build must not drag loose assemblies alongside it. | |
| $dlls = (Get-ChildItem out-aot -Filter *.dll).Count | |
| Write-Host "loose DLLs beside the AOT exe: $dlls" | |
| - name: Smoke test the AOT binary | |
| if: matrix.rid == 'win-x64' # an arm64 binary cannot execute on an x64 runner | |
| shell: pwsh | |
| run: | | |
| # No key exists on a runner, so first-run setup runs and then aborts on EOF — for which | |
| # the app correctly returns a non-zero exit code. That is expected here, so judge the | |
| # rendered output rather than the exit status. | |
| $out = "/quit`n" | ./out-aot/OpenKey.exe 2>&1 | Out-String | |
| $global:LASTEXITCODE = 0 | |
| Write-Host $out | |
| # Each assertion covers a distinct thing AOT could plausibly have broken. | |
| if ($out -notmatch "OpenKey") { throw "no recognisable output — binary likely aborted on startup" } | |
| if ($out -notmatch "Welcome to OpenKey") { throw "first-run copy missing — Spectre rendering is broken" } | |
| if ($out -notmatch "OpenRouter") { throw "setup flow did not render" } | |
| Write-Host "AOT binary starts, renders, and reaches first-run setup." | |
| # always(): the artifact is the point of this workflow, and it is most wanted when a later | |
| # step failed and someone needs to run the binary by hand. | |
| - if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: OpenKey-aot-${{ matrix.rid }} | |
| path: out-aot/OpenKey.exe |