update CONTRIBUTING.md

This commit is contained in:
tapframe 2026-05-13 18:38:21 +05:30
parent 37203d1fc1
commit 95db6db192
4 changed files with 212 additions and 53 deletions

View file

@ -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. -->

View file

@ -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.");

View file

@ -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.
--- ---

View file

@ -1,3 +1,3 @@
CURRENT_PROJECT_VERSION=59 CURRENT_PROJECT_VERSION=61
MARKETING_VERSION=0.1.19 MARKETING_VERSION=0.1.19