From 0af1b46fa52c2bf97abeaac380db88c7d8fba6fe Mon Sep 17 00:00:00 2001 From: "Charles Graham, SWT" Date: Mon, 21 Sep 2026 07:13:16 -0500 Subject: [PATCH 1/2] ci: only remind on missing PR title prefixes --- .github/workflows/pr-title-release-hint.yml | 35 ++++++--------------- CONTRIBUTING.md | 10 +++--- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/.github/workflows/pr-title-release-hint.yml b/.github/workflows/pr-title-release-hint.yml index 6d83dc6..21c4cd9 100644 --- a/.github/workflows/pr-title-release-hint.yml +++ b/.github/workflows/pr-title-release-hint.yml @@ -10,11 +10,11 @@ permissions: issues: write jobs: - hint-title-for-python-changes: + hint-title-format: runs-on: ubuntu-latest steps: - - name: Check PR title against Python changes + - name: Check PR title format uses: actions/github-script@v9 with: script: |- @@ -22,29 +22,10 @@ jobs: const owner = context.repo.owner; const repo = context.repo.repo; const issue_number = pr.number; - const expected = /^(fix|feat|perf|revert|deps|docs)(\([^)\r\n]+\))?!?:\s+\S/; + const expected = /^[a-zA-Z][a-zA-Z0-9-]*(\([^)\r\n]+\))?!?:[^\S\r\n]+\S/; const marker = ""; - const files = await github.paginate( - github.rest.pulls.listFiles, - { - owner, - repo, - pull_number: issue_number, - per_page: 100, - } - ); - - const excludedPythonFiles = new Set([ - "docs/conf.py", - "rtd_docs/conf.py", - ]); - const hasPythonChanges = files.some( - (file) => - file.filename.endsWith(".py") && - !excludedPythonFiles.has(file.filename) - ); - if (!hasPythonChanges || expected.test(pr.title)) { + if (expected.test(pr.title)) { const comments = await github.paginate( github.rest.issues.listComments, { @@ -71,16 +52,20 @@ jobs: } const body = `${marker} - This PR changes Python files, and the title does not match the release naming convention used by \`release-please\`. + Please give this PR a title in the form \`: short description\`. Consider renaming the PR title to one of these forms: - \`fix: short description\` (patch) - \`feat: short description\` (minor) - \`feat!: short description\` (major) + - \`test: short description\` (tests) + - \`docs: short description\` (documentation) + - \`ci: short description\` (CI workflows) + - \`chore: short description\` (maintenance) If this PR will be squash-merged, the PR title often becomes the commit message on the default branch, which affects whether the next release is patch, minor, or major. - Scoped titles such as \`fix(parser): handle missing values\` are also supported. This is an advisory reminder; tests, docs, and maintenance-only changes can use their appropriate Conventional Commit type. + Scoped titles such as \`fix(parser): handle missing values\` and other types such as \`refactor:\` and \`style:\` are also supported. This is an advisory reminder; choose the type that describes the change. A title with a type prefix and a description will not receive this reminder. See the repository guidance in [\`CONTRIBUTING.md\`](https://github.com/${owner}/${repo}/blob/${pr.base.ref}/CONTRIBUTING.md#releases).`; diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e130dd..0df67c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -180,10 +180,12 @@ after the type or scope marks a breaking change. Use `test:`, `ci:`, `build:`, or `chore:` when appropriate; ordinary maintenance commits do not trigger a release on their own. -The PR-title workflow adds an advisory comment when Python files change without -a release-triggering title. It updates the same comment and removes it when the -title is corrected. Sphinx configuration files are excluded. The reminder can -be ignored for test-only or maintenance changes that do not need a release. +The PR-title workflow adds an advisory comment when a title lacks the +`: description` format, regardless of which files change. Any type is +accepted, including `test:`, `ci:`, and `chore:`, as are optional scopes and +breaking-change markers. Titles must include a space after the colon and a +nonempty description. It updates the same comment and removes it when the title +is corrected. This format check does not determine whether a release is needed. Squash merging uses the PR title as the commit subject by default. Check the final subject before merging; Release Please reads commits on `main`, not PR titles From 9e164681b1f2af3383eb06e95c31ed8a38f27aa7 Mon Sep 17 00:00:00 2001 From: "Charles Graham, SWT" Date: Mon, 21 Sep 2026 07:19:14 -0500 Subject: [PATCH 2/2] docs: clarify required version bump markers --- .github/workflows/pr-title-release-hint.yml | 8 ++++++ CONTRIBUTING.md | 30 ++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pr-title-release-hint.yml b/.github/workflows/pr-title-release-hint.yml index 21c4cd9..32355e2 100644 --- a/.github/workflows/pr-title-release-hint.yml +++ b/.github/workflows/pr-title-release-hint.yml @@ -63,6 +63,14 @@ jobs: - \`ci: short description\` (CI workflows) - \`chore: short description\` (maintenance) + **Version bumps require these commit markers:** + - **Major** (\`1.2.3 → 2.0.0\`): mark a breaking change with \`!\` after the type or scope, such as \`feat!:\` or \`fix(parser)!:\`, or include a \`BREAKING CHANGE: description\` footer in the merged commit. **\`feat:\` alone does not trigger a major bump.** + - **Minor** (\`1.2.3 → 1.3.0\`): use \`feat:\` for compatible new functionality, without a breaking-change marker. + - **Patch** (\`1.2.3 → 1.2.4\`): use \`fix:\` for compatible bug fixes. This repository also releases patches for \`perf:\`, \`revert:\`, \`deps:\`, and \`docs:\` without a breaking-change marker. + - Ordinary \`test:\`, \`ci:\`, \`build:\`, \`chore:\`, \`refactor:\`, and \`style:\` commits do not trigger a release on their own. + + The highest required bump across commits since the last release wins: **major over minor over patch**. + If this PR will be squash-merged, the PR title often becomes the commit message on the default branch, which affects whether the next release is patch, minor, or major. Scoped titles such as \`fix(parser): handle missing values\` and other types such as \`refactor:\` and \`style:\` are also supported. This is an advisory reminder; choose the type that describes the change. A title with a type prefix and a description will not receive this reminder. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0df67c4..a4db3fa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -167,18 +167,24 @@ the workflow used by [cwms-cli](https://github.com/HydrologicEngineeringCenter/c Use a Conventional Commit title for changes that should be released: -| Title example | Next release | -| --- | --- | -| `fix: handle missing values` | Patch | -| `fix(parser): handle missing values` | Patch | -| `feat: support a new data source` | Minor | -| `feat!: change the public API` | Major | - -`perf:`, `revert:`, `deps:`, and `docs:` also trigger patch releases with the -Python release strategy. A `BREAKING CHANGE:` footer or `!` -after the type or scope marks a breaking change. Use `test:`, `ci:`, -`build:`, or `chore:` when appropriate; ordinary maintenance commits do not -trigger a release on their own. +| Version bump | Required commit format | When to use it | Example from `1.2.3` | +| --- | --- | --- | --- | +| **Major** | `!` after the type or scope, such as `feat!: ...` or `fix(parser)!: ...`, or a `BREAKING CHANGE: description` footer in the merged commit | Breaking changes that require callers to change their code | `2.0.0` | +| **Minor** | `feat: description` or `feat(scope): description`, without a breaking-change marker | New functionality that preserves compatibility | `1.3.0` | +| **Patch** | `fix: description` or `fix(scope): description`, without a breaking-change marker | Compatible bug fixes | `1.2.4` | + +**A breaking change must be explicitly marked; `feat:` alone produces a minor +bump, not a major bump.** Describe the incompatibility and migration steps in the +PR, and preserve the `!` or `BREAKING CHANGE:` footer in the final merged commit. + +`perf:`, `revert:`, `deps:`, and `docs:` also trigger patch releases with this +repository's Python release strategy when no breaking-change marker is present. +Ordinary `test:`, `ci:`, `build:`, `chore:`, `refactor:`, and `style:` commits do +not trigger a release on their own. Accepting a title prefix does not make it a +release trigger. + +Release Please considers the commits since the last release. The highest required +bump wins: **major over minor over patch**, rather than one bump per PR. The PR-title workflow adds an advisory comment when a title lacks the `: description` format, regardless of which files change. Any type is