Adds a working Windows-only build pipeline for the self-hosted org runner (windows-latest), and fixes the PyInstaller spec so the relay feature is bundled. Verified green end-to-end on the runner (macropad.exe, ~8.5 MB, uploaded as an artifact).
The previous .gitea/workflows/release.yml is left as-is (fully commented/disabled); it targeted GitHub-hosted ubuntu-latest/windows-latest and could not complete with only a self-hosted Windows runner.
What's here
.gitea/workflows/build-windows.yml — runs entirely on windows-latest:
preflight job: fast runner smoke-test (OS/PowerShell/Python) so a broken runner fails in seconds.
build-windows job: provisions Python 3.11, pip install -e . + PyInstaller, builds dist/macropad.exe, uploads it as an artifact, and on a v* tag creates/updates a Gitea release and attaches the exe via the Gitea API.
macropad.spec — declare relay_client + aiohttp as hidden imports (the relay client is imported lazily and was at risk of being dropped from the build); switch the EXE icon to a real .ico.
Macro Pad.ico — multi-size (16–256px) icon generated from Macro Pad.png.
Runner-specific hardening (each fixed after observing a real run)
actions/setup-python hangs inside its Windows tool-cache install on self-hosted runners → replaced with a standalone CPython from nuget (no registry/PATH side effects, idempotent, cached in LOCALAPPDATA; honours a pre-installed 3.11 if present).
Runner has Windows PowerShell 5.1, not pwsh → all steps use shell: powershell, with TLS 1.2 forced for HTTPS and BOM-free GITHUB_ENV writes.
PyInstaller needs an .ico on Windows → ship one.
upload-artifact@v4 needs a backend Gitea doesn't provide → pinned to @v3.
30-minute job timeout so a hang can never run indefinitely.
How to release
Push a tag vX.Y.Z → the workflow builds and attaches macropad.exe to a Gitea release for that tag. Manual builds: run the workflow via Actions → Build Windows → Run workflow (or the API dispatch).
## Summary
Adds a working **Windows-only** build pipeline for the self-hosted org runner (`windows-latest`), and fixes the PyInstaller spec so the relay feature is bundled. Verified green end-to-end on the runner (`macropad.exe`, ~8.5 MB, uploaded as an artifact).
The previous `.gitea/workflows/release.yml` is left as-is (fully commented/disabled); it targeted GitHub-hosted `ubuntu-latest`/`windows-latest` and could not complete with only a self-hosted Windows runner.
## What's here
- **`.gitea/workflows/build-windows.yml`** — runs entirely on `windows-latest`:
- `preflight` job: fast runner smoke-test (OS/PowerShell/Python) so a broken runner fails in seconds.
- `build-windows` job: provisions Python 3.11, `pip install -e .` + PyInstaller, builds `dist/macropad.exe`, uploads it as an artifact, and on a `v*` tag creates/updates a Gitea release and attaches the exe via the Gitea API.
- **`macropad.spec`** — declare `relay_client` + `aiohttp` as hidden imports (the relay client is imported lazily and was at risk of being dropped from the build); switch the EXE icon to a real `.ico`.
- **`Macro Pad.ico`** — multi-size (16–256px) icon generated from `Macro Pad.png`.
## Runner-specific hardening (each fixed after observing a real run)
- `actions/setup-python` hangs inside its Windows tool-cache install on self-hosted runners → replaced with a standalone CPython from **nuget** (no registry/PATH side effects, idempotent, cached in `LOCALAPPDATA`; honours a pre-installed 3.11 if present).
- Runner has Windows PowerShell 5.1, not `pwsh` → all steps use `shell: powershell`, with TLS 1.2 forced for HTTPS and BOM-free `GITHUB_ENV` writes.
- PyInstaller needs an `.ico` on Windows → ship one.
- `upload-artifact@v4` needs a backend Gitea doesn't provide → pinned to `@v3`.
- 30-minute job timeout so a hang can never run indefinitely.
## How to release
Push a tag `vX.Y.Z` → the workflow builds and attaches `macropad.exe` to a Gitea release for that tag. Manual builds: run the workflow via **Actions → Build Windows → Run workflow** (or the API dispatch).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Adds .gitea/workflows/build-windows.yml targeting the org's self-hosted
`windows-latest` runner: sets up Python 3.11, installs the project +
PyInstaller, builds dist/macropad.exe, uploads it as an artifact, and on a
v* tag creates/updates a Gitea release and attaches the exe via the Gitea
API. Runs entirely on Windows (no Linux runner required).
Also declare relay_client + aiohttp as PyInstaller hidden imports so the
relay feature (lazily imported in the GUI) is bundled into the exe.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
actions/setup-python@v5 hangs inside its Windows tool-cache install script on
the self-hosted runner. Replace it with an "Ensure Python 3.11" step that uses
an existing py -3.11 / PATH python if present, otherwise silently installs
Python per-user (no elevation, cannot prompt). Invoke pip/PyInstaller via the
resolved interpreter path, and add a 30-minute job timeout so a hang can no
longer run indefinitely.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- The runner has Windows PowerShell 5.1, not pwsh/PowerShell 7 — switch all
steps from `shell: pwsh` to `shell: powershell`.
- Make the scripts 5.1-safe: force TLS 1.2 for HTTPS, -UseBasicParsing on
Invoke-WebRequest, and write GITHUB_ENV as ascii (no BOM).
- Add a fast `preflight` job that validates the runner (OS, PowerShell, Python
availability) in seconds; build-windows now `needs: [preflight]`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PyInstaller on Windows requires an .ico (or .exe) for the executable icon and
its PNG->ICO auto-conversion did not engage on the runner. Add a multi-size
Macro Pad.ico (16-256px) generated from Macro Pad.png and point macropad.spec
at it. The PNG stays bundled for the runtime window/tray icon.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The per-user MSI installer is stateful across runs on a persistent VM: once a
version is registered, a later /quiet install no-ops and never lands at the new
TargetDir, so python.exe went missing. Switch to a standalone CPython from
nuget cached under LOCALAPPDATA — no registry/PATH changes, idempotent, reused
across runs. A pre-existing Python 3.11 on PATH is still honoured.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
upload-artifact@v4 uses the @actions/artifact v2 backend, which Gitea (reported
to the action as GHES) does not support. Pin to @v3, which uses the artifact
protocol Gitea implements. The exe itself now builds successfully; this was the
only remaining failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jknapp
merged commit 8c3e5106d5 into main2026-07-18 04:08:27 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Adds a working Windows-only build pipeline for the self-hosted org runner (
windows-latest), and fixes the PyInstaller spec so the relay feature is bundled. Verified green end-to-end on the runner (macropad.exe, ~8.5 MB, uploaded as an artifact).The previous
.gitea/workflows/release.ymlis left as-is (fully commented/disabled); it targeted GitHub-hostedubuntu-latest/windows-latestand could not complete with only a self-hosted Windows runner.What's here
.gitea/workflows/build-windows.yml— runs entirely onwindows-latest:preflightjob: fast runner smoke-test (OS/PowerShell/Python) so a broken runner fails in seconds.build-windowsjob: provisions Python 3.11,pip install -e .+ PyInstaller, buildsdist/macropad.exe, uploads it as an artifact, and on av*tag creates/updates a Gitea release and attaches the exe via the Gitea API.macropad.spec— declarerelay_client+aiohttpas hidden imports (the relay client is imported lazily and was at risk of being dropped from the build); switch the EXE icon to a real.ico.Macro Pad.ico— multi-size (16–256px) icon generated fromMacro Pad.png.Runner-specific hardening (each fixed after observing a real run)
actions/setup-pythonhangs inside its Windows tool-cache install on self-hosted runners → replaced with a standalone CPython from nuget (no registry/PATH side effects, idempotent, cached inLOCALAPPDATA; honours a pre-installed 3.11 if present).pwsh→ all steps useshell: powershell, with TLS 1.2 forced for HTTPS and BOM-freeGITHUB_ENVwrites..icoon Windows → ship one.upload-artifact@v4needs a backend Gitea doesn't provide → pinned to@v3.How to release
Push a tag
vX.Y.Z→ the workflow builds and attachesmacropad.exeto a Gitea release for that tag. Manual builds: run the workflow via Actions → Build Windows → Run workflow (or the API dispatch).🤖 Generated with Claude Code