Skip to content

Make --create-release metadata-only; keep asset upload separate #2

Make --create-release metadata-only; keep asset upload separate

Make --create-release metadata-only; keep asset upload separate #2

Workflow file for this run

name: Build Windows Executables (AMD64 + ARM64)
on:
workflow_dispatch:
push:
tags:
- '*'
permissions:
contents: read
jobs:
build-windows:
strategy:
fail-fast: false
matrix:
include:
- runner: windows-2022
arch: amd64
python_version: '3.10'
pip_packages: "pyqt6 pyqtgraph markdown bleak numpy scipy numba fastplotlib PyOpenGL pybind11 setuptools cobs tamp wmi"
- runner: windows-11-arm
arch: arm64
python_version: '3.11'
pip_packages: "pyqt6 pyqtgraph markdown bleak numpy scipy fastplotlib PyOpenGL pybind11 setuptools cobs tamp wmi"
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
id: setup_python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
- name: Show Python version
shell: pwsh
run: |
python --version
python -c "import sys; print(sys.version)"
- name: Install app dependencies
shell: pwsh
run: |
python -m pip install --upgrade pip
python -m pip install ${{ matrix.pip_packages }}
- name: Build executable archive via release.ps1 (with C-accelerated line parser)
id: build_executable
shell: pwsh
run: |
.\scripts\release.ps1 -PythonBin python -BuildExecutable -BuildCAccelerated
- name: Remove bundled MSVCP140.dll files (defensive)
shell: pwsh
run: |
$internalDir = ".\dist\SerialUI\_internal"
$dlls = Get-ChildItem -Path $internalDir -Recurse -Filter MSVCP140.dll -ErrorAction SilentlyContinue
if ($dlls) {
$dlls | ForEach-Object {
Remove-Item -Force $_.FullName
Write-Host "Removed bundled runtime file:"
Write-Host $_.FullName
}
} else {
Write-Host "No bundled MSVCP140.dll files found under $internalDir"
}
- name: Frozen self-test (C parser)
id: c_parser_selftest
shell: pwsh
run: |
$stdoutPath = "c_parser_stdout.txt"
$stderrPath = "c_parser_stderr.txt"
if (Test-Path $stdoutPath) { Remove-Item -Force $stdoutPath }
if (Test-Path $stderrPath) { Remove-Item -Force $stderrPath }
$proc = Start-Process -FilePath ".\dist\SerialUI\SerialUI.exe" -ArgumentList "--selftest-c-parser" -NoNewWindow -Wait -PassThru -RedirectStandardOutput $stdoutPath -RedirectStandardError $stderrPath
$exitCode = $proc.ExitCode
Write-Host "C parser self-test exit code: $exitCode"
Write-Host "C parser self-test stdout:"
if (Test-Path $stdoutPath) { Get-Content $stdoutPath }
Write-Host "C parser self-test stderr:"
if (Test-Path $stderrPath) { Get-Content $stderrPath }
if ($exitCode -ne 0) { throw "Frozen C parser self-test failed with exit code $exitCode" }
- name: Frozen self-test (numba)
id: numba_selftest
if: ${{ matrix.arch != 'arm64' && steps.c_parser_selftest.conclusion == 'success' }}
shell: pwsh
run: |
$stdoutPath = "numba_stdout.txt"
$stderrPath = "numba_stderr.txt"
if (Test-Path $stdoutPath) { Remove-Item -Force $stdoutPath }
if (Test-Path $stderrPath) { Remove-Item -Force $stderrPath }
$proc = Start-Process -FilePath ".\dist\SerialUI\SerialUI.exe" -ArgumentList "--selftest-numba" -NoNewWindow -Wait -PassThru -RedirectStandardOutput $stdoutPath -RedirectStandardError $stderrPath
$exitCode = $proc.ExitCode
Write-Host "Numba self-test exit code: $exitCode"
Write-Host "Numba self-test stdout:"
if (Test-Path $stdoutPath) { Get-Content $stdoutPath }
Write-Host "Numba self-test stderr:"
if (Test-Path $stderrPath) { Get-Content $stderrPath }
if ($exitCode -ne 0) { throw "Frozen numba self-test failed with exit code $exitCode" }
- name: Crash diagnostics (Windows event logs)
if: ${{ always() && (steps.setup_python.conclusion == 'failure' || steps.build_executable.conclusion == 'failure' || steps.c_parser_selftest.conclusion == 'failure' || (matrix.arch != 'arm64' && steps.numba_selftest.conclusion == 'failure')) }}
shell: pwsh
run: |
Write-Host "Step outcomes:"
Write-Host " setup_python: ${{ steps.setup_python.conclusion }}"
Write-Host " build_executable: ${{ steps.build_executable.conclusion }}"
Write-Host " c_parser_selftest: ${{ steps.c_parser_selftest.conclusion }}"
Write-Host " numba_selftest: ${{ steps.numba_selftest.conclusion }}"
Write-Host "Collecting recent Application Error events for SerialUI.exe"
$events = Get-WinEvent -FilterHashtable @{LogName='Application'; Id=1000; StartTime=(Get-Date).AddMinutes(-30)} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'Faulting application name: SerialUI.exe' } |
Select-Object -First 5 -ExpandProperty Message
if ($events) {
$events | ForEach-Object { Write-Host "-----"; Write-Host $_ }
} else {
Write-Host "No matching Application Error (ID=1000) events found in the last 30 minutes."
}
Write-Host "Collecting recent Windows Error Reporting events (ID=1001) for SerialUI.exe"
$werEvents = Get-WinEvent -FilterHashtable @{LogName='Application'; Id=1001; StartTime=(Get-Date).AddMinutes(-30)} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'SerialUI.exe|SerialUI' } |
Select-Object -First 5 -ExpandProperty Message
if ($werEvents) {
$werEvents | ForEach-Object { Write-Host "-----"; Write-Host $_ }
} else {
Write-Host "No matching Windows Error Reporting (ID=1001) events found in the last 30 minutes."
}
Write-Host "Recent Application log events related to SerialUI/parser/runtime:"
Get-WinEvent -FilterHashtable @{LogName='Application'; StartTime=(Get-Date).AddMinutes(-30)} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'SerialUI.exe|simple_parser|header_parser|python3[0-9]{2}\.dll|MSVCP140.dll' } |
Select-Object -First 10 TimeCreated, Id, ProviderName, Message |
Format-List
Write-Host "Checking for remaining bundled MSVCP140.dll files"
Get-ChildItem .\dist\SerialUI\_internal -Recurse -Filter MSVCP140.dll -ErrorAction SilentlyContinue |
Select-Object FullName, Length
Write-Host "Checking bundled parser extensions"
Get-ChildItem .\dist\SerialUI\_internal -Recurse -Filter *.pyd -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match 'simple_parser|header_parser' } |
Select-Object FullName, Length
Write-Host "Attempting parser extension load via host python (diagnostic only)"
@'
import os
import sys
import ctypes
import traceback
from pathlib import Path
root = Path("dist/SerialUI/_internal")
parser_dir = root / "helpers" / "line_parsers"
print(f"root={root}")
print(f"parser_dir={parser_dir}")
if hasattr(os, "add_dll_directory"):
for d in (root, root / "winrt", parser_dir):
if d.exists():
try:
os.add_dll_directory(str(d))
print(f"add_dll_directory ok: {d}")
except Exception as exc:
print(f"add_dll_directory failed: {d}: {exc}")
for pyd in sorted(parser_dir.glob("*.pyd")):
if "simple_parser" not in pyd.name and "header_parser" not in pyd.name:
continue
print(f"loading {pyd}")
try:
ctypes.WinDLL(str(pyd))
print(" WinDLL load: ok")
except Exception as exc:
print(f" WinDLL load failed: {exc!r}")
try:
sys.path.insert(0, str(root))
import helpers.line_parsers.simple_parser # noqa: F401
import helpers.line_parsers.header_parser # noqa: F401
print("python import helpers.line_parsers: ok")
except Exception:
print("python import helpers.line_parsers failed:")
traceback.print_exc()
'@ | Set-Content -Encoding UTF8 .\diag_parser_import.py
python .\diag_parser_import.py
Remove-Item -Force .\diag_parser_import.py -ErrorAction SilentlyContinue
Write-Host "Captured self-test logs (if available):"
foreach ($p in @("c_parser_stdout.txt","c_parser_stderr.txt","numba_stdout.txt","numba_stderr.txt")) {
if (Test-Path $p) {
Write-Host "----- $p -----"
Get-Content $p
}
}
- name: Upload build artifacts
if: ${{ always() && steps.build_executable.conclusion == 'success' }}
uses: actions/upload-artifact@v4
with:
name: SerialUI-windows-${{ matrix.arch }}-${{ github.ref_name }}-${{ github.run_number }}
if-no-files-found: error
retention-days: 14
path: |
dist/SerialUI-*.zip
dist/SerialUI