diff --git a/.github/llm-review-rules.md b/.github/llm-review-rules.md new file mode 100644 index 00000000000000..1985c0d2194183 --- /dev/null +++ b/.github/llm-review-rules.md @@ -0,0 +1,152 @@ +# LLM review rules — openwrt/packages + +The review routine reads this at session start. +General contribution rules (commit subject prefix, +Signed-off-by, real-name author, line length) live in +[`CONTRIBUTING.md`](../CONTRIBUTING.md). + +## Review posture + +Separate formatting that changes what gets built from formatting that +is only a matter of taste. + +The first kind is a real defect and belongs in a review: a space where +make expects a tab in a recipe, indentation in `conffiles` or in an +install scriptlet that ends up inside the generated file, CRLF line +endings, a `define` block that is never closed. These break the build +or ship a broken package, and severity does not depend on how small +the diff looks. + +The second kind — alignment, blank lines, the order of `KEY:=value` +entries, a house style a package has not followed for years — is +secondary. Maintainers here would rather merge a correct change with a +small style wart than hold it up over one, so: + +- Lead with correctness, security and packaging bugs. Keep cosmetic + remarks few, mark them as optional, and say plainly which findings + (if any) actually block a merge. +- Do not restate what the formality bot already posted. Sign-off, + no-reply e-mail, subject/body length, CRLF, `PKG_VERSION` / + `PKG_RELEASE`, `conffiles` layout, patch headers and OpenWrt + metadata are checked by [`formalities.json`](formalities.json). + The rules below explain the reasoning behind those checks and cover + what the bot cannot see — they are not a second checklist to run. +- CI is a reference, not a gate. A red job can just as easily be a gap + in the test harness as a defect in the PR. Describe what failed and + leave the call to the maintainer instead of demanding a green run. + +## Package Version and Release (`PKG_VERSION`, `PKG_RELEASE`) + +- **Reset release on upgrade.** When a package's `PKG_VERSION` is updated/upgraded, the `PKG_RELEASE` must be reset to `1`. +- **Increment release on modification.** When modifying build logic, adding patches, changing dependencies (`DEPENDS`), or modifying configuration/scripts (e.g. init scripts, hotplug handlers) without updating `PKG_VERSION`, the `PKG_RELEASE` must be incremented. +- **Do not increment release for minor changes.** Cosmetic edits (e.g., typos in comments, copyright updates, formatting/whitespace), changing the package maintainer (`PKG_MAINTAINER`), or updating source download info (`PKG_SOURCE_URL` / `PKG_HASH`) do not require incrementing `PKG_RELEASE`. + +## Patches + +### Patch regeneration + +OpenWrt patches are quilt-managed and **not** refreshed with `git format-patch`. When a patch's hunk headers, fuzz, or context need to be regenerated, the project-specific command is: + +- `make package//refresh` (e.g. `make package/lsof/refresh`) + +If a patch's metadata or format is incorrect, recommend using the matching `make package//refresh` command, not `git format-patch`. + +### Patch metadata / format + +A patch that is a candidate for upstream submission should be +upstream-ready, which means it carries: +- A descriptive subject and body explaining why the patch is needed. +- A valid `Signed-off-by` header matching the patch author. +- An upstream reference, pull request link, or `Upstream-Status` indicating if/where the patch has been submitted upstream. + +This bar is not meant for every patch in the feed. Many are +OpenWrt-specific hacks — cross-compile fixes, toolchain and path +adjustments, musl workarounds — that will never be sent anywhere, and +plenty are one or two lines whose intent is obvious from the diff +itself. There a short subject is enough: do not ask for a written +justification of a self-evident change, and do not ask for an upstream +reference on a patch that has no upstream to go to. Reserve the full +requirement for patches that are non-trivial or that change behaviour +in a way a reader cannot infer. + +## Package Sources and Mirrors + +- **Prefer archive tarballs over git clones.** `PKG_SOURCE_PROTO:=git` should only be used as a last resort if no release tarballs (xz, gz, bzip2, zip) are available. +- **Use mirror macros.** Prefer predefined mirror macros (e.g., `@GITHUB`, `@SF`, `@GNU`, `@GNOME`, `@SAVANNAH`, `@APACHE`, `@KERNEL`) in `PKG_SOURCE_URL` rather than hardcoding the full domain. + +## Avoid reuse of `PKG_NAME` + +- Do not reuse the `PKG_NAME` variable in `call`, `define`, and `eval` lines. Use the literal name of the package instead to improve readability. + - *Correct:* `$(eval $(call BuildPackage,lsof))` + - *Incorrect:* `$(eval $(call BuildPackage,$(PKG_NAME)))` + +## Makefile indentation + +Which character to indent a `define` block with depends on what the +block is — make only requires tabs where the block is a recipe: + +- **Two spaces** for metadata blocks, whose body is a list of + `KEY:=value` lines: `define Package/` and + `define KernelPackage/`. +- **Tabs** for blocks whose body is shell run by make as a recipe: + `define Build/*` (`Build/Configure`, `Build/Compile`, + `Build/InstallDev`, …) and `define Package//install`. +- **No indentation** for blocks that are written out verbatim as a + file: `define Package//conffiles` (see below) and the + `preinst` / `postinst` / `prerm` / `postrm` scriptlets. Both go + through `BuildPackVariable` in `include/package-pack.mk`, which + echoes the block into a generated file — leading whitespace ends up + inside the resulting shell script rather than in a make recipe. +- `define Package//description` (free-form prose) and + `define Package//config` (Kconfig syntax, not `KEY:=value`) + have no enforced convention. Two spaces dominate for the former and + tabs for the latter, but neither is worth a comment on its own. + +Only raise indentation on lines the PR actually touches. A package +that has used a different style throughout for years is not something +a version bump has to fix. + +## Package testing (CI / Runtime tests) + +- **Generic version check.** The CI automatically runs generic runtime checks on all package executables, executing them with version/help flags (e.g. `--version`, `--help`) and expecting the output to contain `PKG_VERSION`. +- **Add `test-version.sh` for overrides.** If the package executables do not support these flags or do not output the version string, the generic test will fail. To override/bypass this check, a `test-version.sh` script must be added to the package's directory (e.g. checking the package name and returning 0). +- **Add `test.sh` for custom tests.** A `test.sh` script can be added for custom runtime tests. Note that because generic tests are forced by default in CI, `test-version.sh` is still required if the executables fail the generic version check. +- **Avoid quiet mode in grep.** Do not use `grep -q` (or `--quiet`) in `test.sh` or `test-version.sh` scripts when checking output or version strings. Leaving the matched lines in the output ensures that the printed version or status is logged and visible in CI/CD build logs. + +## Init Scripts + +- **Use procd.** Service/init scripts (installed to `/etc/init.d/`) must use the procd process management system. They must include `USE_PROCD=1` and define `start_service()`. +- **Avoid legacy backgrounding.** Do not use manually written daemon management (e.g. backgrounding with `&`, custom `stop()` loops, manual PID files) unless there is a strong, explicitly stated reason. +- **Shebang.** All init scripts must use the shebang `#!/bin/sh /etc/rc.common`. + +## Configuration Files (`conffiles`) + +- **Register config files.** If a package installs user-modifiable configuration files (typically under `/etc/config/` or `/etc/`), they must be registered in the `define Package//conffiles` section. +- **Correct path formatting.** + - Absolute paths must be used (starting with `/`). + - Directories must end with a trailing slash `/`. + - Individual files must NOT end with a trailing slash. + - No indentation is allowed (do not start lines with spaces or tabs). + +## Maintainer Info + +- **New packages require a maintainer.** When a new package is introduced, a `PKG_MAINTAINER` field must be defined in the Makefile, formatted as `Name `. + +## Backports / cherry-picks + +PRs targeting `openwrt-NN.NN` branches or titled `[X.Y] ...` are +backports. Their diffs should match the upstream commit on `master` +verbatim. Code-style or packaging issues that already exist on the +upstream commit belong on a fix-to-master PR, not on the backport — +flag only deviations introduced by the cherry-pick itself, plus +the missing `(cherry picked from commit )` trailer. +`git cherry-pick -x` adds the trailer automatically. + +Not every stable-branch PR is a cherry-pick, though. A stable branch +can legitimately carry a version that no longer exists on `master`: +typically a minor update inside an LTS series that the branch stays +pinned to, while `master` has already moved on to a newer major. Such +a PR has no upstream commit to compare against and no +`cherry picked from` trailer to ask for. Review it on its own merits +and check only that the update stays inside the series the branch +already ships.