From 77caf815ecdda323afa1ad0f3821ef75c65e9cea Mon Sep 17 00:00:00 2001 From: Val Neekman Date: Fri, 16 Oct 2026 11:32:24 -0400 Subject: [PATCH] Adopt an issues-first contribution policy Add a pull-request template that asks contributors to open an issue first, a CONTRIBUTING guide explaining why, bug and feature issue templates, and a short README pointer. Generating a pull request is cheap, but verifying one against the frozen legacy output contract is not, and that cost falls on the maintainer. Pull requests are now reviewed only after an issue has been opened and the change agreed there; security fixes excepted. Docs and templates only. No library behavior changes, no release. --- .github/ISSUE_TEMPLATE/bug_report.md | 30 ++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/feature_request.md | 23 ++++++++++ .github/pull_request_template.md | 30 ++++++++++++ AGENTS.md | 1 + CONTRIBUTING.md | 56 +++++++++++++++++++++++ README.md | 9 ++++ 7 files changed, 154 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100644 CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..f2ac972 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,30 @@ +--- +name: Bug report +about: Report a slug that comes out wrong, or an error you hit +title: "" +labels: "" +assignees: "" +--- + +**What happened** + + +**What you expected** + + +**Example** (short and runnable, if you can) + +```python +from slugify import slugify + +slugify("...") +``` + +**Versions** + +- python-slugify: +- Python: +- Transliteration backend (`text-unidecode`, `Unidecode`, or `anyascii`): +- Algorithm: default (`legacy`) or `algorithm='modern'`: + +**Does this affect slugs you have already stored?** diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..e563d8d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Contributing guide + url: https://github.com/un33k/python-slugify/blob/master/CONTRIBUTING.md + about: Please read this first — this project is issues first, and unsolicited pull requests are closed. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..11be74b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest a change or an addition +title: "" +labels: "" +assignees: "" +--- + +**The problem you're trying to solve** + + +**What you'd like instead** + + +**Your use case** (what are you building, and how often does this come up?) + + +**Would this change existing output?** + +python-slugify's default `legacy` output never changes, because deployed sites +depend on the slugs it has already produced. New behavior has to sit behind the +explicit `algorithm='modern'` opt-in. Say whether that's acceptable for your +request. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..c225a7a --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,30 @@ +## Please open an issue first + +This project is **issues first**. We do not review unsolicited pull requests. + +Generating a pull request is cheap now. Verifying one against this library's +frozen output contract is not, and that cost lands on the maintainer. So the +order here is: + +1. Open an **issue** describing a real problem you hit, with an example. +2. If we agree it needs fixing, we'll fix it, or say so on the issue — then a + pull request against that issue is welcome. + +**A pull request with no linked, agreed issue will be closed with thanks,** +however good the code is. Please don't take that personally; several fine +pieces of work have been turned away for exactly this reason. + +Before you submit, check what applies to you: + +- [ ] This pull request links an issue where the change was agreed +- [ ] This is a security fix +- [ ] Neither — I should close this and open an issue instead + +## If your pull request was agreed + +- Which issue does it close? +- What did you change, and how did you verify it? +- Does it touch `slugify/_legacy.py` or `tests/test_legacy.py`? Those are frozen: + any change to legacy output is rejected. New behavior belongs behind + `algorithm='modern'`. +- Did you run `python -m pytest`, `python -m mypy`, and the style checks? diff --git a/AGENTS.md b/AGENTS.md index 7c60e4a..3308740 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,6 +38,7 @@ This is the single, top-level agent guidance file for this repository. ## Issue and PR handling +- This repository is issues first. Unsolicited external pull requests are closed with thanks, however good the code; a pull request is reviewed only after an issue has been opened and the change agreed there (security fixes excepted). Generating a pull request is cheap, verifying one against the frozen legacy output is not, and that cost falls on the maintainer. Decline gently, verify claims before repeating them, and invite an issue describing a real problem. Maintainer pull requests against `master` remain the normal release path. - Read each item and verify what the implementation actually addresses. Distinguish incorporated, superseded, partially addressed, declined and deferred work, including modern-only fixes. - When authorized to consolidate/close items, add an individual explanatory cross-reference to the aggregate PR and a disposition index there. Credit contributors; never represent a closed-unmerged PR as merged or deferred work as implemented. - Identify agent-authored interactions as Dojo. For every Dojo-authored interaction in this repository—including opening, replying to, reviewing, or closing issues, pull requests, discussions, and releases—end the authored body or comment with the following attribution as the final line, separated from preceding content by a blank line: `🚀 Generated with [Dojo](https://heydojo.ai) ⛩️` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2a0ec67 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,56 @@ +# Contributing + +Thanks for wanting to help. This project keeps contributions simple on purpose. + +## Issues first + +**Open an issue before writing code.** We do not review unsolicited pull requests. + +A pull request costs almost nothing to produce now, but verifying one is the +expensive part, and that cost falls on the maintainer. python-slugify also has a +hard compatibility promise: the default `legacy` output must never change, +because deployed sites depend on the exact slugs it has already produced. Every +proposed change has to be checked against that promise, which takes real time. + +So the order is: + +1. **Open an issue.** Describe a real problem you ran into. Include the input, + what you got, what you expected, and the versions involved. +2. **Wait for a decision.** If we agree it needs fixing, we'll say so on the + issue. Then a pull request is welcome, or we'll fix it ourselves. + +A pull request with no linked, agreed issue will be closed with thanks. That is +not a judgment on the code — good work has been turned away for this reason +alone. Security fixes are the one exception. + +## What makes an issue easy to act on + +- A short, runnable example that shows the problem. +- The `python-slugify` version, the Python version, and which transliteration + backend you use (`text-unidecode`, `Unidecode`, or `anyascii`). +- Whether the problem is in the default (`legacy`) behavior or in + `algorithm='modern'`. +- Whether it affects slugs you have already stored. + +## If your pull request was agreed + +- Branch off `master` and open the pull request against `master`. +- Link the issue, and keep the change as small as the fix allows. +- Never change legacy output. `slugify/_legacy.py` and `tests/test_legacy.py` + are frozen. Output-changing improvements belong behind the explicit + `algorithm='modern'` opt-in. +- Add coverage for changed behavior under `tests/`. +- Run the checks before submitting: + + ```sh + python -m pytest + python -m mypy + python tools/check_dist.py + ``` + +- Update `CHANGELOG.md` only if asked; the maintainer writes release notes. + +## Releases + +Releases are made by the maintainer, and only when shipped library behavior +changes. Documentation, test, and CI changes do not get their own release. diff --git a/README.md b/README.md index 2a68581..41480be 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,15 @@ The installed package set and the backend used at runtime are different question text-unidecode from a normal installation. This is factual dependency guidance, not legal advice or a blanket assurance about your application's obligations. Evaluate the actual versions, distribution method, and applicable license terms. +## Bugs and ideas + +Open an [issue](https://github.com/un33k/python-slugify/issues) with a concrete +input and expected result. This project is issues first: we don't review +unsolicited pull requests, because verifying a change against the frozen legacy +output is the expensive part and it lands on the maintainer. If an issue is +accepted, we'll fix it or welcome a pull request for it. See +[CONTRIBUTING](CONTRIBUTING.md). + ## Sponsors [Neekware Inc.](https://neekware.com) — creator of [Dojo Workspace](https://heydojo.ai), your AI workspace for building, learning, and getting things done.