mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 07:21:58 +00:00
update CONTRIBUTING.md
This commit is contained in:
parent
37203d1fc1
commit
95db6db192
4 changed files with 212 additions and 53 deletions
58
.github/PULL_REQUEST_TEMPLATE.md
vendored
58
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -4,44 +4,64 @@
|
||||||
|
|
||||||
## PR type
|
## PR type
|
||||||
|
|
||||||
<!-- Pick one and delete the others -->
|
<!-- Check exactly one. PRs outside these types are not accepted. -->
|
||||||
- Bug fix
|
- [ ] Reproducible bug fix
|
||||||
- Small maintenance improvement
|
- [ ] UI glitch/bug fix
|
||||||
- Docs fix
|
- [ ] Behavior bug/regression fix
|
||||||
- Translation update
|
- [ ] Small maintenance only, with no UI or behavior change
|
||||||
- Approved larger change (link approval below)
|
- [ ] Docs accuracy fix
|
||||||
|
- [ ] Translation/localization only
|
||||||
|
- [ ] Approved larger or directional change
|
||||||
|
|
||||||
## Why
|
## Why
|
||||||
|
|
||||||
<!-- Why this change is needed. Link bug/issue/context. -->
|
<!-- Why this change is needed. Explain the user-visible bug, regression, maintenance need, docs error, or approved request. -->
|
||||||
|
|
||||||
|
## Issue or approval
|
||||||
|
|
||||||
|
<!-- Required. Link the bug issue or approved feature request. For docs/translation/maintenance with no issue, explain why no issue is needed. -->
|
||||||
|
<!-- Examples: Fixes #123 / Approved in #456 / No linked issue: typo-only docs fix. -->
|
||||||
|
|
||||||
|
## UI / behavior impact
|
||||||
|
|
||||||
|
<!-- Check every box that applies. At least one must be checked. -->
|
||||||
|
- [ ] No UI change
|
||||||
|
- [ ] No behavior change
|
||||||
|
- [ ] UI changed only to fix a documented glitch/bug
|
||||||
|
- [ ] Behavior changed only to fix a documented bug/regression
|
||||||
|
- [ ] UI change has explicit maintainer approval
|
||||||
|
- [ ] Behavior change has explicit maintainer approval
|
||||||
|
|
||||||
## Policy check
|
## Policy check
|
||||||
|
|
||||||
<!-- ALL boxes must be checked or the PR will be closed without review. -->
|
<!-- ALL boxes must be checked or the PR will be closed without review. -->
|
||||||
- [ ] This PR is not cosmetic-only, unless it is a translation PR.
|
- [ ] I have read and understood `CONTRIBUTING.md`.
|
||||||
- [ ] This PR does not add a new major feature without prior approval.
|
- [ ] This PR is small, focused, and limited to one problem.
|
||||||
- [ ] This PR is small in scope and focused on one problem.
|
- [ ] This PR is not cosmetic-only.
|
||||||
- [ ] If this is a larger or directional change, I linked the **approved** feature request issue below.
|
- [ ] Any UI change fixes a linked glitch/bug and includes visual proof, or this PR has no UI change.
|
||||||
|
- [ ] Any behavior change fixes a linked bug/regression or has explicit approval, or this PR has no behavior change.
|
||||||
|
- [ ] This PR does not bundle unrelated refactors, cleanups, formatting, or drive-by changes.
|
||||||
|
- [ ] This PR does not add dependencies, architecture changes, migrations, or product-direction changes without explicit approval.
|
||||||
|
- [ ] I listed the testing performed below.
|
||||||
|
|
||||||
> **Large PRs without a linked, approved feature request issue will be closed immediately without review. No exceptions.**
|
> UI polish, cosmetic-only changes, minor behavior tweaks, and unapproved product changes will be closed without review.
|
||||||
|
|
||||||
## Approved feature request (required for large/non-trivial PRs)
|
## Scope boundaries
|
||||||
|
|
||||||
<!-- Link the approved feature request issue. Delete this section ONLY for small bug fixes. -->
|
<!-- List anything intentionally not changed. If this is a bug fix, confirm it does not include extra UI polish or behavior tweaks. -->
|
||||||
<!-- Example: Approved in #123 -->
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
<!-- What you tested and how (manual + automated). -->
|
<!-- What you tested and how. Include devices/emulators, commands, and manual flows. Do not write only "not tested" unless this is docs/translation-only. -->
|
||||||
|
|
||||||
## Screenshots / Video (UI changes only)
|
## Screenshots / Video (UI changes only)
|
||||||
|
|
||||||
<!-- If UI changed, add before/after screenshots or a short clip. -->
|
<!-- Required for any UI change. Write "Not a UI change" only if no UI changed. -->
|
||||||
|
|
||||||
## Breaking changes
|
## Breaking changes
|
||||||
|
|
||||||
<!-- Any breaking behavior/config/schema changes? If none, write: None -->
|
<!-- Any breaking behavior/config/schema changes? If none, write: None. -->
|
||||||
|
|
||||||
## Linked issues
|
## Linked issues
|
||||||
|
|
||||||
<!-- Example: Fixes #123 -->
|
<!-- Required for bug fixes, UI glitch fixes, behavior fixes, and approved changes. For docs/translation/maintenance with no issue, write: No linked issue - reason. -->
|
||||||
|
|
|
||||||
102
.github/workflows/pr-template-check.yml
vendored
102
.github/workflows/pr-template-check.yml
vendored
|
|
@ -29,9 +29,44 @@ jobs:
|
||||||
return (next === -1 ? rest : rest.slice(0, next)).trim();
|
return (next === -1 ? rest : rest.slice(0, next)).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
const required = ["Summary", "Why", "Testing", "Breaking changes", "Linked issues"];
|
function cleanedContent(title) {
|
||||||
|
const content = sectionContent(title);
|
||||||
|
if (content === null) return null;
|
||||||
|
return content
|
||||||
|
.replace(/<!--[\s\S]*?-->/g, "")
|
||||||
|
.replace(/`/g, "")
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkedLines(content) {
|
||||||
|
return (content || "").match(/^\s*-\s+\[[xX]\]\s+.+$/gm) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function uncheckedLines(content) {
|
||||||
|
return (content || "").match(/^\s*-\s+\[\s\]\s+.+$/gm) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasIssueReference(content) {
|
||||||
|
return /(^|\s)(#\d+|https:\/\/github\.com\/\S+\/issues\/\d+)/i.test(content || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
const required = [
|
||||||
|
"Summary",
|
||||||
|
"PR type",
|
||||||
|
"Why",
|
||||||
|
"Issue or approval",
|
||||||
|
"UI / behavior impact",
|
||||||
|
"Policy check",
|
||||||
|
"Scope boundaries",
|
||||||
|
"Testing",
|
||||||
|
"Screenshots / Video",
|
||||||
|
"Breaking changes",
|
||||||
|
"Linked issues",
|
||||||
|
];
|
||||||
const missing = [];
|
const missing = [];
|
||||||
const empty = [];
|
const empty = [];
|
||||||
|
const failedRules = [];
|
||||||
|
|
||||||
for (const name of required) {
|
for (const name of required) {
|
||||||
const content = sectionContent(name);
|
const content = sectionContent(name);
|
||||||
|
|
@ -40,34 +75,73 @@ jobs:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleaned = content
|
const cleaned = cleanedContent(name);
|
||||||
.replace(/<!--[\s\S]*?-->/g, "")
|
const normalized = cleaned.toLowerCase();
|
||||||
.replace(/`/g, "")
|
const allowsNone = name === "Breaking changes" || name === "Screenshots / Video";
|
||||||
.replace(/\s+/g, " ")
|
|
||||||
.trim()
|
|
||||||
.toLowerCase();
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
cleaned.length < 4 ||
|
cleaned.length < 4 ||
|
||||||
cleaned === "none" ||
|
(!allowsNone && ["none", "n/a", "na", "not applicable"].includes(normalized)) ||
|
||||||
cleaned.includes("what changed in this pr") ||
|
normalized.includes("what changed in this pr") ||
|
||||||
cleaned.includes("why this change is needed") ||
|
normalized.includes("why this change is needed") ||
|
||||||
cleaned.includes("what you tested") ||
|
normalized.includes("what you tested") ||
|
||||||
cleaned.includes("example: fixes #123")
|
normalized.includes("example: fixes #123")
|
||||||
) {
|
) {
|
||||||
empty.push(name);
|
empty.push(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (missing.length || empty.length) {
|
const prTypeContent = sectionContent("PR type") || "";
|
||||||
|
const prTypeChecked = checkedLines(prTypeContent);
|
||||||
|
if (sectionContent("PR type") !== null && prTypeChecked.length !== 1) {
|
||||||
|
failedRules.push("Check exactly one PR type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const impactContent = sectionContent("UI / behavior impact") || "";
|
||||||
|
const impactChecked = checkedLines(impactContent);
|
||||||
|
if (sectionContent("UI / behavior impact") !== null && impactChecked.length === 0) {
|
||||||
|
failedRules.push("Check at least one UI / behavior impact box.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const policyContent = sectionContent("Policy check") || "";
|
||||||
|
const policyChecked = checkedLines(policyContent);
|
||||||
|
const policyUnchecked = uncheckedLines(policyContent);
|
||||||
|
if (sectionContent("Policy check") !== null && policyChecked.length === 0) {
|
||||||
|
failedRules.push("Policy check must include checked boxes.");
|
||||||
|
}
|
||||||
|
if (policyUnchecked.length) {
|
||||||
|
failedRules.push("Every Policy check box must be checked.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkedTypeText = prTypeChecked.join(" ");
|
||||||
|
const issueRequired =
|
||||||
|
/bug fix|ui glitch|behavior bug|approved larger|approved directional/i.test(checkedTypeText);
|
||||||
|
const issueText = [
|
||||||
|
cleanedContent("Issue or approval") || "",
|
||||||
|
cleanedContent("Linked issues") || "",
|
||||||
|
].join(" ");
|
||||||
|
if (issueRequired && !hasIssueReference(issueText)) {
|
||||||
|
failedRules.push("Bug fixes, UI glitch fixes, behavior fixes, and approved changes must link an issue or approved request.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const uiChanged = checkedLines(impactContent).some((line) =>
|
||||||
|
/UI changed only to fix a documented glitch\/bug|UI change has explicit maintainer approval/i.test(line)
|
||||||
|
);
|
||||||
|
const screenshotText = (cleanedContent("Screenshots / Video") || "").toLowerCase();
|
||||||
|
if (uiChanged && ["none", "n/a", "na", "not a ui change", "not applicable"].includes(screenshotText)) {
|
||||||
|
failedRules.push("UI changes must include before/after screenshots or video.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missing.length || empty.length || failedRules.length) {
|
||||||
const lines = [
|
const lines = [
|
||||||
"PR description is missing required detail.",
|
"PR description is missing required detail.",
|
||||||
"",
|
"",
|
||||||
];
|
];
|
||||||
if (missing.length) lines.push(`Missing sections: ${missing.join(", ")}`);
|
if (missing.length) lines.push(`Missing sections: ${missing.join(", ")}`);
|
||||||
if (empty.length) lines.push(`Incomplete sections: ${empty.join(", ")}`);
|
if (empty.length) lines.push(`Incomplete sections: ${empty.join(", ")}`);
|
||||||
|
if (failedRules.length) lines.push(`Failed policy rules: ${failedRules.join(" ")}`);
|
||||||
lines.push("");
|
lines.push("");
|
||||||
lines.push("Please fill the PR template before merging.");
|
lines.push("Please complete the PR template and make sure the PR fits CONTRIBUTING.md before review.");
|
||||||
core.setFailed(lines.join("\n"));
|
core.setFailed(lines.join("\n"));
|
||||||
} else {
|
} else {
|
||||||
core.info("PR template check passed.");
|
core.info("PR template check passed.");
|
||||||
|
|
|
||||||
103
CONTRIBUTING.md
103
CONTRIBUTING.md
|
|
@ -2,33 +2,84 @@
|
||||||
|
|
||||||
Thanks for helping improve Nuvio.
|
Thanks for helping improve Nuvio.
|
||||||
|
|
||||||
## Strict rules — read before opening anything
|
## Strict rules - read before opening anything
|
||||||
|
|
||||||
These rules are enforced strictly. Issues and PRs that do not follow them will be closed without review.
|
These rules are enforced strictly. Issues and PRs that do not follow them will be closed without review.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## PR policy
|
## What PRs are for
|
||||||
|
|
||||||
Pull requests are currently intended for:
|
Pull requests are accepted only when they fit one of these categories:
|
||||||
|
|
||||||
- Reproducible bug fixes
|
- Reproducible bug fixes for documented issues
|
||||||
- Small stability improvements
|
- UI glitch fixes for visible bugs or regressions, with before/after proof
|
||||||
- Minor maintenance work
|
- Behavior bug fixes that restore expected behavior without changing product direction
|
||||||
|
- Small maintenance work that does not change UI, UX, behavior, dependencies, architecture, or public contracts
|
||||||
- Small documentation fixes that improve accuracy
|
- Small documentation fixes that improve accuracy
|
||||||
- Translation updates
|
- Translation/localization updates
|
||||||
|
|
||||||
Pull requests are generally **not** accepted for:
|
Pull requests are not accepted for:
|
||||||
|
|
||||||
- New major features
|
- New major features
|
||||||
- Product direction changes
|
- Product direction changes
|
||||||
- Large UX / UI redesigns
|
- UX/UI redesigns
|
||||||
- Cosmetic-only changes
|
- Cosmetic-only UI changes
|
||||||
- Refactors without a clear user-facing or maintenance benefit
|
- "Minor polish" changes to colors, spacing, typography, icons, copy, layout, animations, or visual style
|
||||||
|
- Behavior changes that are not tied to a reproducible bug or approved feature request
|
||||||
|
- Refactors without a clear maintenance need
|
||||||
|
- Dependency additions or architecture changes without prior approval
|
||||||
|
|
||||||
Translation PRs are allowed, as long as they stay focused on translation/localization work and do not bundle unrelated feature or UI changes.
|
Translation PRs are allowed, as long as they stay focused on translation/localization work and do not bundle unrelated feature or UI changes.
|
||||||
|
|
||||||
### Large PRs and large changes
|
---
|
||||||
|
|
||||||
|
## UI changes
|
||||||
|
|
||||||
|
Do not open a pull request for a UI change just because it looks better, cleaner, more modern, or more consistent to you.
|
||||||
|
|
||||||
|
UI PRs are accepted only when they fix a specific, documented glitch or bug, such as:
|
||||||
|
|
||||||
|
- Broken layout
|
||||||
|
- Overlapping or clipped text
|
||||||
|
- Unreadable content
|
||||||
|
- Incorrect visual state
|
||||||
|
- Navigation, gesture, or focus glitches
|
||||||
|
- A visible regression from a previous version
|
||||||
|
- A crash, blank screen, or unusable screen caused by UI code
|
||||||
|
|
||||||
|
Every UI PR must include:
|
||||||
|
|
||||||
|
- A linked bug issue
|
||||||
|
- A short explanation of the exact glitch being fixed
|
||||||
|
- Before and after screenshots or a short video
|
||||||
|
- The smallest possible change that fixes the glitch
|
||||||
|
|
||||||
|
Cosmetic-only UI PRs will be closed, even if the change is small.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Behavior changes
|
||||||
|
|
||||||
|
Behavior includes, but is not limited to, playback, stream/source selection, resume state, watched state, search, sync, settings defaults, navigation, gestures, error handling, caching, networking, storage, downloads, offline behavior, and account-related flows.
|
||||||
|
|
||||||
|
Do not open a PR that changes behavior unless one of these is true:
|
||||||
|
|
||||||
|
- It fixes a linked, reproducible bug or regression and restores the intended behavior.
|
||||||
|
- It links an approved feature request where a maintainer explicitly approved implementation.
|
||||||
|
|
||||||
|
Behavior PRs must explain:
|
||||||
|
|
||||||
|
- The old behavior
|
||||||
|
- The broken or unwanted behavior
|
||||||
|
- The new behavior
|
||||||
|
- How the behavior was tested
|
||||||
|
|
||||||
|
Minor behavior tweaks are still behavior changes. They need the same issue link or approval.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Large PRs and large changes
|
||||||
|
|
||||||
**Any large PR or change that is not a simple bug fix must be discussed and approved via a feature request issue first.**
|
**Any large PR or change that is not a simple bug fix must be discussed and approved via a feature request issue first.**
|
||||||
|
|
||||||
|
|
@ -38,7 +89,9 @@ Translation PRs are allowed, as long as they stay focused on translation/localiz
|
||||||
|
|
||||||
PRs that introduce large changes without a linked, approved feature request **will not be reviewed at all** and will be closed immediately. No exceptions.
|
PRs that introduce large changes without a linked, approved feature request **will not be reviewed at all** and will be closed immediately. No exceptions.
|
||||||
|
|
||||||
This applies to — but is not limited to — UI changes, new features, architecture changes, dependency additions, and large refactors.
|
This applies to UI changes, behavior changes, new features, architecture changes, dependency additions, large refactors, migrations, and changes that affect product direction.
|
||||||
|
|
||||||
|
Approval means a maintainer has clearly said the implementation is approved. A feature request being open, popular, or labeled `enhancement` is not approval.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -100,14 +153,26 @@ Opening a feature request does **not** mean a pull request will be accepted for
|
||||||
|
|
||||||
Please make sure your PR is all of the following:
|
Please make sure your PR is all of the following:
|
||||||
|
|
||||||
- Small in scope
|
- Allowed by this policy
|
||||||
- Focused on one problem
|
- Small in scope and focused on one problem
|
||||||
- Clearly aligned with the current direction of the project
|
- Clearly aligned with the current direction of the project
|
||||||
- Not cosmetic-only, unless it is a translation PR
|
- Not cosmetic-only
|
||||||
- Not a new major feature unless it was discussed and approved first
|
- Not changing behavior unless it fixes a linked bug or has explicit approval
|
||||||
- **If large or non-trivial: linked to an approved feature request issue**
|
- Not changing UI unless it fixes a linked glitch/bug and includes visual proof
|
||||||
|
- Not bundling refactors, cleanups, or drive-by changes with a bug fix
|
||||||
|
- Tested manually and/or automatically in a way that matches the risk
|
||||||
|
- Linked to an approved feature request issue if large, directional, or non-trivial
|
||||||
|
|
||||||
PRs that do not fit this policy will be closed without merge so review time can stay focused on bugs, regressions, and small improvements.
|
PRs will be closed without review if they:
|
||||||
|
|
||||||
|
- Are cosmetic-only UI changes
|
||||||
|
- Change behavior without a linked bug or approved feature request
|
||||||
|
- Change UI without screenshots/video
|
||||||
|
- Bundle unrelated changes
|
||||||
|
- Leave the PR template incomplete
|
||||||
|
- Add dependencies, architecture changes, or broad refactors without approval
|
||||||
|
|
||||||
|
Review time is reserved for bugs, regressions, stability, translations, documentation accuracy, and approved work.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
CURRENT_PROJECT_VERSION=59
|
CURRENT_PROJECT_VERSION=61
|
||||||
MARKETING_VERSION=0.1.19
|
MARKETING_VERSION=0.1.19
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue