Files
punktfunk/docs/releases
enricobuehlerandClaude Opus 5 384a0adc83
android-screenshots / screenshots (push) Successful in 1m32s
audit / cargo-audit (push) Successful in 38s
audit / bun-audit (plugin-kit) (push) Successful in 20s
audit / bun-audit (sdk) (push) Successful in 15s
audit / bun-audit (web) (push) Successful in 15s
audit / docs-site-audit (push) Successful in 14s
audit / pnpm-audit (push) Successful in 16s
android / android (push) Successful in 5m17s
apple / swift (push) Successful in 5m7s
audit / license-gate (push) Successful in 4m33s
decky / build-publish (push) Successful in 48s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 14s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 12s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 51s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 1m3s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 24s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 20s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 35s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 35s
sbom / sbom (push) Successful in 1m17s
linux-client-screenshots / screenshots (push) Successful in 3m43s
docker / deploy-docs (push) Successful in 19s
docker / builders-arm64cross (push) Successful in 13s
web-screenshots / screenshots (push) Successful in 4m25s
ci / web (push) Successful in 1m6s
ci / rust-arm64 (push) Successful in 3m51s
flatpak / build-publish (push) Successful in 5m18s
ci / docs-site (push) Successful in 1m48s
deb / build-publish (push) Successful in 4m0s
deb / build-publish-client-arm64 (push) Successful in 1m45s
arch / build-publish (push) Successful in 8m9s
ci / rust (push) Successful in 8m20s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 2m50s
deb / build-publish-host (push) Successful in 5m8s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 4m1s
windows-host / package (push) Successful in 11m9s
windows-host / winget-source (push) Skipped
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 2m41s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 3m1s
release / apple (push) Successful in 26m25s
apple / screenshots (push) Successful in 20m53s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m21s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 19m39s
chore(release): bump workspace version to 0.22.2
Patch release: 0.22.0 and 0.22.1 gave every default-configured Windows host a
controller no game could see. The pf-dualsense -> pf-gamepad package rename also
renamed a HARDWARE id, so PnP matched none of our models, fell through to the
devnode's synthesized USB ids and let Microsoft's inbox input.inf win — HidUsb
cannot start on a software-enumerated devnode, and without a start there is no
device interface to answer a channel proof. This cut carries that one-line
restore, the [Models]-vs-host guard test, and the Punktfunk display-name rebrand
across the Windows devices and firewall rules.

Windows hosts only; clients and Linux hosts are untouched.

Versions-only lock diff, hand-applied: the 30 workspace-member entries move
0.22.1 -> 0.22.2. Two sets of third-party crates deliberately share our version
space and are untouched — `base64` at 0.22.1, and the eight gtk-rs crates at
0.22.0 (cairo/gdk-pixbuf/gio/graphene/pango); a blanket sed would corrupt both,
so the bump matches on member name only. `cargo metadata --locked` exits 0 on
the pinned toolchain. Release notes in docs/releases/v0.22.2.md seed the release
body per the Model-1 flow.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 12:36:11 +02:00
..

Release notes

One file per stable release: docs/releases/vX.Y.Z.md. Its contents become the Gitea release body verbatim and are the source of the Discord #releases announcement.

Why this exists

Releases used to be created by CI with an empty body; the notes were pasted in by hand afterward. That left a window where the release — and anything announcing it — carried no notes. Now the notes are authored before the tag is pushed, as part of the version bump, so the release is born complete and the announcement always has something to say.

The flow

  1. Write the notes. Add docs/releases/vX.Y.Z.md in the same commit (or PR) as the version bump. Copy TEMPLATE.md and fill it in. This file is the single source of truth for the body.
  2. Tag & push. git tag -a vX.Y.Z … && git push origin vX.Y.Z fans out to the build workflows. Whichever one wins the create race seeds the release body from this file (scripts/ci/gitea-release.shensure_release, and its PowerShell twin). The release page shows the notes immediately.
  3. Wait for green. Let every platform's CI finish and go green.
  4. Announce. Dispatch the announce workflow (.gitea/workflows/announce.yml) with the tag. It re-asserts this file over the live release (so any late edit wins) and posts an embed to Discord #releases. Pressing "go" is the quality gate — a half-built release is never announced. Stable-only; a -rc tag is refused unless allow_prerelease=true.

Editing the notes after the tag is fine: update this file, then re-run step 4 (or PATCH the body via the API) — the announce step always re-syncs from the file, so the file stays authoritative even across a tag re-point.

Canary / -rc builds have no file here on purpose: they get no curated body and are not announced.

Voice & format

Write for the people who USE Punktfunk to stream their games and desktops — not for the people who build it. A non-engineer should finish knowing what's new and whether it affects them; an engineer should never be confused or forced to decode internals. (See any recent vX.Y.Z.md for the target.)

  1. Lead with the benefit. Each entry = what the user can now do, what now works, or what stopped going wrong — in their words. Implementation is not the story.
  2. No internal vocabulary in the body. No protocol/message names, code type names, hex codes or hardware IDs, crate/component names, or API symbols. Translate any essential detail to plain language. Name things users recognize (iPad, Apple Pencil, Steam Deck, Android TV, the Windows sign-in screen) — not subsystems.
  3. Group as New / Improved / Fixed, each a bold one-line lead-in + a tight plain explanation. Skimmable. The lead-in text before the first ## is what the Discord announcement shows, so make it a real, plain-language summary.
  4. Be specific and honest — no vague "various improvements"; a reader should know exactly what changed.
  5. Compatibility line up top, in plain terms: can they update one side at a time? does their existing setup keep working? No version numbers in the lead.
  6. All protocol / ABI / driver / embedder detail goes in ONE ## Under the hood (for developers) section at the very bottom — the only place internal names and version numbers belong, clearly optional. The old dense engineering style survives only there.

The short annotated-tag message stays separate and short (a headline + a paragraph); it is the tag object's message, not this file.