forked from unom/punktfunk
WP4 of the docs-and-onboarding overhaul (punktfunk-planning design/docs-and-onboarding-overhaul.md). scripts/install.sh — plain POSIX sh (dash-clean), ~380 lines, `curl -fsSL https://punktfunk.unom.io/install.sh | sh`: detect the distro from os-release (apt / dnf / pacman / rpm-ostree→sysext; NixOS, SteamOS, Windows and unknown distros get a one-line pointer and stop; Debian 12 / Ubuntu 24.04 / Mint 22 / Fedora 45 hit the documented floors with the right docs link) → install with the platforms.json lines VERBATIM (channel and the Fedora group are edited into the string at run time; `--yes` rewrites them non-interactive, a tty hands the package manager its own prompt; stdin is never read, because under `curl | sh` stdin is the script) → `punktfunk-host detect-conflicts` (exit 1 = active Sunshine-family host) → offer to keep both by moving the management API port (PUNKTFUNK_MGMT_BIND, default 47991, the firewall step opens it) → input group (ujust on Bazzite; no-op if already in) → optional punktfunk group, GameStream compat, shared clipboard (all default no) → firewalld/ufw profiles → enable host + console (+ the plugin runner where it isn't) → optional linger → verify (unit active, UDP 9777 bound) and print the console URL, the password command and the pairing steps. `--dry-run` prints every command and changes nothing; every prompt has a PUNKTFUNK_INSTALL_* environment twin; re-running is safe (install skipped when the binary exists). Running under sudo is refused (host.env and the units belong to the user); root without sudo gets a shim so the verbatim lines still work. Decisions: the canonical URL is punktfunk.unom.io/install.sh, a 302 on the website to the script at raw/branch/main (versioned with the code it installs; precedent: the Bazzite sysext bootstrap) — the website half is punktfunk-website PR #4. GPU drivers stay the docs pages' job; the one silent failure (Fedora + NVIDIA without RPM Fusion's ffmpeg-libs → no NVENC) is called out at the end. Gates: check-docs-drift.sh gate 6 — every apt/pacman/dnf/sysext install line in data/platforms.json must appear verbatim in the script, and the script must parse (shown to fail on a planted drift). New path-filtered workflow installer-smoke.yml runs the script unattended in debian:trixie, fedora:44 and archlinux:base against the real registry, then `punktfunk-host --version`, `detect-conflicts`, and a re-run that must say "already installed". Docs: install hub gains "Guided install (preview)" rendered from platforms.json's new `installer` block via an <Installer/> component (one-liner + inspect-first form + flags); CONTRIBUTING names the new gate. Verified locally: sh/dash -n, both docs gates, docs-site build + lint, and a --dry-run matrix over 16 faked os-release files (all four families, every floor, canary, every option, piped stdin). The container run itself is the CI job's to report — Docker on this machine was wedged under another session's emulated build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
128 lines
6.7 KiB
Markdown
128 lines
6.7 KiB
Markdown
# Contributing to Punktfunk
|
|
|
|
Thanks for your interest in contributing!
|
|
|
|
## Licensing of contributions (inbound = outbound)
|
|
|
|
Punktfunk is dual-licensed under **MIT OR Apache-2.0**.
|
|
|
|
> Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
|
|
> the work by you, as defined in the Apache-2.0 license, shall be dual licensed as **MIT OR
|
|
> Apache-2.0**, without any additional terms or conditions.
|
|
|
|
By opening a pull request you agree to license your contribution under these terms. This is the
|
|
standard Rust-ecosystem "inbound = outbound" model; it keeps the project's licensing unambiguous
|
|
(including the Apache-2.0 §5 contributor patent grant) and any future relicensing clean. You retain
|
|
the copyright to your contributions.
|
|
|
|
### Do not paste copyleft (or otherwise incompatibly-licensed) code
|
|
|
|
The single thing that could poison the permissive license is **copied source from a copyleft
|
|
project**. Several adjacent projects (Sunshine, Apollo, Moonlight) are GPL-3.0. You may study them
|
|
and reimplement a *technique*, protocol, or wire format — those are not copyrightable — but **never
|
|
paste their code**, and do not translate a GPL implementation line-by-line. When a comment credits
|
|
prior art, make clear it is an independent reimplementation, not a copy. The same applies to any
|
|
third party's code under a license incompatible with MIT/Apache.
|
|
|
|
If you add a new third-party dependency, it must be permissive (MIT / Apache-2.0 / BSD / ISC / Zlib /
|
|
Unicode-3.0 / etc.). `about.toml` holds the accepted-license allow-list; regenerate the attribution
|
|
file with `scripts/gen-third-party-notices.sh` when the dependency tree changes.
|
|
|
|
## Prerequisites
|
|
|
|
The Rust toolchain is **pinned exactly** in `rust-toolchain.toml`; rustup installs it for you the
|
|
first time you build, so don't override it — a different rustc reformats files nobody touched.
|
|
|
|
The workspace links real system libraries, so a bare `cargo build --workspace` fails on a stock
|
|
machine. The authoritative list is what CI installs, in `ci/rust-ci.Dockerfile` — on **Ubuntu 26.04**,
|
|
which is what gets you FFmpeg 8:
|
|
|
|
```sh
|
|
sudo apt install build-essential clang libclang-dev pkg-config cmake \
|
|
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavfilter-dev libavdevice-dev \
|
|
libpipewire-0.3-dev libopus-dev libwayland-dev libxkbcommon-dev \
|
|
libgl-dev libegl-dev libgbm-dev \
|
|
libgtk-4-dev libadwaita-1-dev libsdl3-dev \
|
|
libvulkan-dev
|
|
```
|
|
|
|
(The last two groups are the Linux client shell and the Vulkan session presenter; skip them only
|
|
if you never build those crates. `libvulkan-dev` is for the LOADER's pkg-config/soname — ash
|
|
dlopens it, and the client links no FFmpeg at all, so no libav*-dev appears here.
|
|
`scripts/bootstrap-ubuntu.sh` sets up an Ubuntu **capture-test host** — NVIDIA, Sway, PipeWire —
|
|
and is not a substitute for the list above.)
|
|
|
|
## Before you push
|
|
|
|
Enable the repo git hooks once per clone — they run the exact rustfmt gates CI runs (main
|
|
workspace + the UMDF driver workspace) on every commit and push, so a push can never fail CI
|
|
on formatting alone:
|
|
|
|
```sh
|
|
git config core.hooksPath scripts/git-hooks
|
|
```
|
|
|
|
Then the usual full pass. Use `--locked` as CI does — otherwise a silent `Cargo.lock` update can pass
|
|
locally and fail CI:
|
|
|
|
```sh
|
|
cargo fmt --all --check
|
|
cargo clippy --workspace --all-targets --locked -- -D warnings
|
|
cargo test --workspace --locked
|
|
```
|
|
|
|
Two more gates that only apply to some changes:
|
|
|
|
- **Touched `web/` or `docs-site/`?** CI builds and typechecks both. Run, in that directory:
|
|
```sh
|
|
bun install && bun run build && bun run lint
|
|
```
|
|
Build first — it generates the API client / MDX typegen that the typecheck imports.
|
|
- **Touched Windows- or Linux-gated code from another OS?** `scripts/xcheck.sh windows` (or
|
|
`linux`) type-checks and lints that platform's `#[cfg(target_os = …)]` code in about a second,
|
|
instead of waiting for the CI job that compiles it.
|
|
|
|
Generated artifacts are checked in. `include/punktfunk_core.h` (cbindgen) is regenerated by the build
|
|
and CI fails if the committed copy drifts. `api/openapi.json` is gated the same way: the `rust` job
|
|
regenerates the spec and diffs it against the committed file, and the `docs-drift` job checks that
|
|
`docs-site/public/openapi.json` — the snapshot the docs site serves — is a byte-for-byte copy of it.
|
|
Touch the management API and CI stays red until you regenerate and re-copy:
|
|
|
|
```sh
|
|
cargo run -p punktfunk-host -- openapi > api/openapi.json
|
|
cp api/openapi.json docs-site/public/openapi.json
|
|
```
|
|
|
|
## Where facts live (docs vs READMEs vs website)
|
|
|
|
Every user-facing fact has exactly one canonical home; everything else links to it. Duplicated
|
|
walkthroughs are how the docs drifted before — don't add new ones.
|
|
|
|
| Surface | Owns | Never contains |
|
|
|---|---|---|
|
|
| [docs-site](https://docs.punktfunk.unom.io) (`docs-site/content/`) | All user-facing facts: install, config, features, troubleshooting | Design rationale |
|
|
| READMEs (root, `packaging/*`, `scripts/*`) | Dev/packager rationale and pointers into the docs | User walkthroughs duplicated from docs-site |
|
|
| [punktfunk.unom.io](https://punktfunk.unom.io) (separate repo) | Marketing, downloads, blog | Instructions — it deep-links the docs instead |
|
|
| punktfunk-planning (private) | Design rationale, RFCs, plans | Anything user-facing |
|
|
|
|
Docs pages are written for one of two audiences, not both at once: the **get-started track**
|
|
(quickstart, install, pairing — short, one task per page, happy path only) assumes no Linux
|
|
expertise; the **reference track** (configuration, CLI, API, per-compositor pages) is allowed to be
|
|
dense. When a change touches a user-facing fact, update the docs-site page that owns it in the same
|
|
PR.
|
|
|
|
CI enforces the cheap half of this (`scripts/ci/check-docs-drift.sh` and `check-docs-links.sh`):
|
|
the OpenAPI snapshot must match `api/openapi.json`, the docs-site copy of `data/platforms.json` must
|
|
match the canonical one, `scripts/install.sh` must carry the file's install lines verbatim, every `PUNKTFUNK_*` variable the docs mention
|
|
must still exist in the tree, the counts of undocumented `PUNKTFUNK_*` variables and undocumented
|
|
`punktfunk-host` subcommands may never grow (document the new knob, or consciously raise the
|
|
baseline in the script), and internal docs links must resolve.
|
|
|
|
Match the surrounding code's comment density and naming. Commit messages end with the
|
|
`Co-Authored-By` trailer (see `git log`).
|
|
|
|
See the [README's Build & test section](README.md#build--test-from-source) for the extra dev
|
|
commands (the FEC loss harness, the standalone C-ABI proof) and
|
|
[Design invariants](README.md#design-invariants) for the rules a change is expected to hold to, and
|
|
the [docs site](https://docs.punktfunk.unom.io) for architecture and per-platform guides.
|