Two separate failures on the first run.
Linux could not compile the native module: it needs libpipewire-0.3-dev, which
its README states and the apt list omitted.
Windows built everything, native module verified, then died on the upload with
a bare JSONDecodeError. The cause was curl -sf, which discards the error body,
so a failed release creation surfaced as an empty pipe and no reason at all.
The step now captures status and body and prints them, treats a failed create
as possibly the other matrix job having just created it, and passes
target_commitish so the tag can be created.
Embedded python gave way to jq: a multi-line heredoc inside a YAML literal
block ends the block at the first unindented line, which is how the file became
invalid YAML in the first place.
GitHub stays the build machine — it has the Windows runners the native audio
module needs — but the update feed moves to this fork's own Gitea.
The GitHub repository is private, and electron-updater against a private GitHub
repo needs a token inside the shipped app, which is a leaked token. Gitea
serves release assets to anyone, so the installer carries no credential. The
flow was verified end to end against the live instance before writing this:
create release, upload asset, download anonymously.
The release tag is fixed at 'latest' because electron-updater fetches
latest.yml before it knows which version exists, so the URL cannot carry a
version; CI replaces that release's assets each publish. electron-builder runs
with --publish never since it cannot upload to Gitea, but still emits the
latest.yml the updater reads.
Needs a GITEA_TOKEN secret on the GitHub repository.