From 52d986c133dc78c4049f7a4a9f06a3246fea554c Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Mon, 19 Oct 2026 13:59:55 +0700 Subject: [PATCH] ci: drop the PR title length cap and the banned-words gate --- .claude/rules/ci.md | 2 +- .github/pull_request_template.md | 4 ++-- .github/workflows/pr-title.yml | 12 +----------- AGENTS.md | 4 ++-- linux/AGENTS.md | 2 +- linux/CONTRIBUTING.md | 2 +- scripts/ci/check-pr-title.py | 6 ------ scripts/ci/test_check_pr_title.py | 28 ---------------------------- 8 files changed, 8 insertions(+), 52 deletions(-) diff --git a/.claude/rules/ci.md b/.claude/rules/ci.md index 909a8a6a32..5a8ac833d0 100644 --- a/.claude/rules/ci.md +++ b/.claude/rules/ci.md @@ -100,7 +100,7 @@ The required check names are in `AGENTS.md` (CI). Reading a red check: `.claude/ ## PR title (`pr-title.yml`) - Runs on opened, edited, reopened and synchronize, so every head commit gets the check. -- Runs `scripts/ci/check-pr-title.py`, then `scripts/ci/check-changelog.py --pr` on the merge commit's diff to its first parent, which also refuses a release PR that changes more than `apple/CHANGELOG.md` and `apple/changelog.d/`, then `scripts/check-banned-words.sh` on the PR's added lines and on its body. The banned-words step runs both and exits with the worse result. +- Runs `scripts/ci/check-pr-title.py`, then `scripts/ci/check-changelog.py --pr` on the merge commit's diff to its first parent, which also refuses a release PR that changes more than `apple/CHANGELOG.md` and `apple/changelog.d/`. ## Repo Hygiene (`repo-hygiene.yml`) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1bdc68f1bf..80a3b3b368 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,11 +1,11 @@ ## Why diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml index eaae645c77..fbfd7e8616 100644 --- a/.github/workflows/pr-title.yml +++ b/.github/workflows/pr-title.yml @@ -28,7 +28,7 @@ jobs: scripts apple/scripts/release - - name: Check the title is a Conventional Commits subject within 72 characters + - name: Check the title is a Conventional Commits subject env: TITLE: ${{ github.event.pull_request.title }} run: python3 scripts/ci/check-pr-title.py "$TITLE" @@ -38,13 +38,3 @@ jobs: PR: ${{ github.event.pull_request.number }} TITLE: ${{ github.event.pull_request.title }} run: python3 scripts/ci/check-changelog.py --pr "$PR" --title "$TITLE" --base "$GITHUB_BASE_REF" - - - name: Check the added lines and the description against the banned words - env: - BODY: ${{ github.event.pull_request.body }} - run: | - printf '%s\n' "$BODY" > "$RUNNER_TEMP/pr-body.md" - status=0 - scripts/check-banned-words.sh --base HEAD^1 || status=1 - scripts/check-banned-words.sh "$RUNNER_TEMP/pr-body.md" || status=1 - exit "$status" diff --git a/AGENTS.md b/AGENTS.md index 5f076f69fb..e3821ff654 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,7 +27,7 @@ Each app has its own guide beside its code: `apple/AGENTS.md` and `linux/AGENTS. ## Writing style and docs - All writing: short sentences, plain words, specific numbers and names, no em dash, no filler. -- `scripts/banned-words.txt` is the list; never copy its terms. `scripts/check-banned-words.sh --staged` checks a staged change; the `PR title` job checks a PR's added lines and body. +- `scripts/banned-words.txt` is the list; never copy its terms. `scripts/check-banned-words.sh --staged` checks a staged change. - One home per fact; others point to it by repo path and section. No drifting counts or timings; a plan is not a fact. - Code comments say why, never what. Delete what-comments in code you touch. - A path in a platform's docs is relative to its folder; a root doc writes it from the repository root. @@ -36,7 +36,7 @@ Each app has its own guide beside its code: `apple/AGENTS.md` and `linux/AGENTS. ## Commits and PRs -- The PR title is the squash commit subject; branch commits use the same format. The body follows `.github/pull_request_template.md`, whose top comment holds the format, types and scopes. The `PR title` check (`scripts/ci/check-pr-title.py`) enforces the format and 72 characters, not scopes. +- The PR title is the squash commit subject; branch commits use the same format. The body follows `.github/pull_request_template.md`, whose top comment holds the format, types and scopes. The `PR title` check (`scripts/ci/check-pr-title.py`) enforces the format, not scopes. - A user-visible change adds a fragment to its app's `changelog.d/`; only a release PR edits a `CHANGELOG.md`. Format: `.claude/rules/changelog.md`. - A rename or signature change updates every caller and test in the same commit. diff --git a/linux/AGENTS.md b/linux/AGENTS.md index f96ace980b..48046e7eca 100644 --- a/linux/AGENTS.md +++ b/linux/AGENTS.md @@ -47,7 +47,7 @@ From the repository root, through the verification wrapper, which keeps the full 2. **Changelog.** A user-visible change adds `linux/changelog.d/..md`, never `apple/changelog.d/`; only a release PR edits `linux/CHANGELOG.md`. Format: the root `.claude/rules/changelog.md`. 3. **Translations.** User-facing strings go through `crate::i18n` (`gettext`, `gettext_f` with named placeholders, `ngettext_f`, `pgettext`). A new or removed file under `crates/app/src` or `data/resources` regenerates `po/POTFILES.in`. See `po/README.md`. 4. **Lint** the workspace: rustfmt, then clippy with and without default features. -5. **Commits and pull requests** follow the root rules: Conventional Commits, at most 72 characters, scope `linux` or `linux-` (for example `linux-grid`, `linux-storage`), and the root `.github/pull_request_template.md`. +5. **Commits and pull requests** follow the root rules: Conventional Commits, scope `linux` or `linux-` (for example `linux-grid`, `linux-storage`), and the root `.github/pull_request_template.md`. ## CI diff --git a/linux/CONTRIBUTING.md b/linux/CONTRIBUTING.md index 79d0768bce..384eecbddb 100644 --- a/linux/CONTRIBUTING.md +++ b/linux/CONTRIBUTING.md @@ -117,7 +117,7 @@ This is the most common substantive change. Follow [docs/adding-drivers.md](docs ## Commits -Conventional Commits, single line, at most 72 characters, same rule as the macOS app. The scope is `linux`, or `linux-` for one area of the app: `linux-grid`, `linux-browse`, `linux-structure`, `linux-editor`, `linux-history`, `linux-export`, `linux-sidebar`, `linux-picker`, `linux-session`, `linux-storage`, `linux-ssh`, `linux-core`, `linux-flatpak`, or a driver as `linux-postgres`, `linux-mysql`, `linux-sqlite`, `linux-mssql`, `linux-clickhouse`. +Conventional Commits, single line, same rule as the macOS app. The scope is `linux`, or `linux-` for one area of the app: `linux-grid`, `linux-browse`, `linux-structure`, `linux-editor`, `linux-history`, `linux-export`, `linux-sidebar`, `linux-picker`, `linux-session`, `linux-storage`, `linux-ssh`, `linux-core`, `linux-flatpak`, or a driver as `linux-postgres`, `linux-mysql`, `linux-sqlite`, `linux-mssql`, `linux-clickhouse`. ``` fix(linux-sidebar): keep the filter text when the catalog refreshes diff --git a/scripts/ci/check-pr-title.py b/scripts/ci/check-pr-title.py index bcb7785be2..b1feaa96ce 100644 --- a/scripts/ci/check-pr-title.py +++ b/scripts/ci/check-pr-title.py @@ -4,10 +4,7 @@ import sys TYPES = ("feat", "fix", "refactor", "perf", "test", "docs", "build", "ci", "chore", "style", "revert") -MAX_TITLE = 72 SUBJECT = re.compile(rf"^(?:{'|'.join(TYPES)})(?:\([a-z0-9][a-z0-9-]*\))?!?: \S") -# A pick into a release line keeps its subject from main, whose trailing (#N) names its origin. -PROVENANCE = re.compile(r" \(#[0-9]+\)$") def problems(title): @@ -19,9 +16,6 @@ def problems(title): + ", ".join(TYPES) + " and the scope is lowercase words joined by hyphens, for example `fix(editor): keep the caret`" ) - length = len(PROVENANCE.sub("", title, count=1)) - if length > MAX_TITLE: - found.append(f"the title is {length} characters, over the {MAX_TITLE} limit") return found diff --git a/scripts/ci/test_check_pr_title.py b/scripts/ci/test_check_pr_title.py index f80ce884ca..c4e0c61cef 100644 --- a/scripts/ci/test_check_pr_title.py +++ b/scripts/ci/test_check_pr_title.py @@ -40,34 +40,6 @@ def test_a_missing_description_is_refused(self): self.assertEqual(len(check.problems("fix(editor):no space")), 1) -class LengthTests(unittest.TestCase): - def test_the_title_alone_is_measured(self): - title = "fix: " + "x" * (check.MAX_TITLE - len("fix: ")) - self.assertEqual(check.problems(title), []) - self.assertEqual(len(check.problems(title + "x")), 1) - - def test_a_long_title_in_the_wrong_shape_reports_both(self): - self.assertEqual(len(check.problems("Fix " + "x" * 100)), 2) - - def test_a_picks_trailing_pull_request_number_is_not_counted(self): - title = "fix: " + "x" * (check.MAX_TITLE - len("fix: ")) - self.assertEqual(check.problems(title + " (#3443)"), []) - self.assertEqual(check.problems("chore(release): v0.82.0 (#3601)"), []) - problems = check.problems(title + "x (#3443)") - self.assertEqual(len(problems), 1) - self.assertIn("73 characters", problems[0]) - - def test_only_one_trailing_pull_request_number_is_skipped(self): - title = "fix: " + "x" * (check.MAX_TITLE - len("fix: ")) - self.assertIn("77 characters", check.problems(title + " (#1) (#2)")[0]) - - def test_a_number_that_is_not_at_the_end_is_counted(self): - title = "fix: " + "x" * (check.MAX_TITLE - len("fix: ") - len(" (#3443)")) - self.assertEqual(check.problems(title + " (#3443)"), []) - self.assertEqual(len(check.problems(title + " (#3443)x")), 1) - self.assertEqual(len(check.problems(title + "x (#3443) ")), 1) - - class OutputTests(unittest.TestCase): def run_main(self, *argv): captured = io.StringIO()