Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 18 additions & 25 deletions .github/workflows/pr-title-release-hint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,22 @@ 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: |-
const pr = context.payload.pull_request;
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 = "<!-- pr-title-release-hint -->";

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,
{
Expand All @@ -71,16 +52,28 @@ 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 \`<type>: 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)

**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\` 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).`;

Expand Down
42 changes: 25 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,31 @@ 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.

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.
| 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
`<type>: 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
Expand Down
Loading