Skip to content

ci: lint the PR title, and match the analyzer's preset to the notes generator - #71

Merged
Ethan-Arrowood merged 4 commits into
mainfrom
fix/release-conventions
Oct 8, 2026
Merged

Ethan-Arrowood merged 4 commits into
mainfrom
fix/release-conventions

Conversation

@Ethan-Arrowood

Copy link
Copy Markdown
Member

Follow-up to the missed release for #65. main has the use cache work but no version was cut: semantic-release ran and reported Analysis of 1 commits complete: no release.

Why

Squash is the only merge method on this repo, and squash_merge_commit_title is COMMIT_OR_PR_TITLE — so for any PR with more than one commit, GitHub uses the PR title as the subject of the commit that lands on main. That subject is the only thing semantic-release reads for the release type; the feat:/fix: subjects of the squashed commits end up in the body, where the parser does not look.

verify-commits.yaml passed because wagoid/commitlint-github-action lints the commits inside the PR. All 30 of #65's were conventional. The squash then replaced them with the one string nothing ever linted.

It has happened twice:

PR Commits Title Result
#68 3 fix: match ISR cache rows… released 2.2.5
#41 7 Use Harper readonly mode for Next.js builds no release — shipped inside 2.2.5 with no note of its own
#65 30 Back the `use cache` directive… no release

Changes

  • verify-commits.yaml — a pr-title job linting the PR title on every pull request. edited is already in the trigger list, so retitling re-checks.
  • .releaserc.json — preset: conventionalcommits on @semantic-release/commit-analyzer, matching the notes generator.
  • CONTRIBUTING.md — the rules and a type-to-release table.

The preset is not just tidiness

commit-analyzer had no preset and so defaulted to angular, while the notes generator was explicitly conventionalcommits. angular does not recognise the ! breaking-change shorthand, so feat!: … — which @commitlint/config-conventional accepts — analysed as no release at all. A breaking change announced that way would have shipped without a major, or without any version.

Verification

Ran analyzeCommits directly against both presets:

Commit angular conventionalcommits
feat: minor minor
fix: / perf: patch patch
proper revert: patch patch
BREAKING CHANGE: footer major major
feat!: none major
docs: / test: / chore(deps): / refactor: none none
the #65 subject as it landed none none

Only feat!: differs, and the new preset is the correct answer. The last row reproduces the defect: the subject that landed on main yields no release under either preset — which is what the PR-title lint prevents.

Not covered here

squash_merge_commit_title is a repository setting, not a file. It is currently COMMIT_OR_PR_TITLE, so a single-commit PR uses that commit's subject instead of the title. Setting it to PR_TITLE would make the linted string always the one that lands. Worth doing, but it needs a repo admin.

🤖 Generated with Claude Code

…enerator

Squash is the only merge method here, and `squash_merge_commit_title` is
COMMIT_OR_PR_TITLE, so for any PR with more than one commit the PR title
becomes the subject of the commit that lands on main — and that subject is the
only thing semantic-release reads. commitlint sees the commits inside the PR,
which the squash then discards, so a title with no conventional type is a
silent no-release. #41 shipped inside 2.2.5 with no note of its own, and #65
produced no release at all.

A title check now runs on every pull request, including on `edited`, so a
retitle re-checks.

`@semantic-release/commit-analyzer` also carried no `preset` and so defaulted
to `angular`, while the notes generator was explicitly `conventionalcommits`.
The two now match. That is not only tidiness: `angular` does not recognise the
`!` breaking-change shorthand, so `feat!: …` passed commitlint and then
analysed as no release at all. Verified against both presets — `feat!:` is
`none` under angular and `major` under conventionalcommits; every other type
agrees.

CONTRIBUTING gains the rules and a type-to-release table.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request configures the @semantic-release/commit-analyzer plugin to use the conventionalcommits preset in .releaserc.json and adds a new 'Commits and releases' section to CONTRIBUTING.md to document the release process and conventional commit requirements. The feedback suggests expanding the commit types table in the documentation to include other common non-releasing types like style, build, and ci for completeness.

Comment thread CONTRIBUTING.md Outdated
Ethan-Arrowood and others added 3 commits October 8, 2026 12:31
The `!` is read only from the commit subject and a `BREAKING CHANGE:` footer
only from the body, so under squash merging the bang counts in the PR title
while the footer counts in a commit inside the PR. Both verified against the
configured analyzer, including the shape GitHub actually produces.

Also rewraps the section: the file keeps a paragraph on one line, and the
first draft hard-wrapped at 100 columns.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The no-release row named four of the seven. `style`, `build` and `ci` are
declared in .releaserc.json too, and all three analyse as no release.

Also notes that "none" is about triggering a release, not visibility: every
declared type has its own section, so it still appears in the notes of
whatever release it rides along in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both came in with the release config and neither is used here. Removing them
from the presetConfig changes nothing about release types — both still analyse
as no release — but such a commit is now hidden from the notes rather than
given its own section.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Ethan-Arrowood
Ethan-Arrowood marked this pull request as ready for review October 8, 2026 20:27
@Ethan-Arrowood
Ethan-Arrowood merged commit 9ebd026 into main Oct 8, 2026
13 checks passed
@Ethan-Arrowood
Ethan-Arrowood deleted the fix/release-conventions branch October 8, 2026 20:34
github-actions Bot pushed a commit that referenced this pull request Oct 8, 2026
## [2.3.0](v2.2.5...v2.3.0) (2026-10-08)

### Features

* back the `use cache` directive with Harper and persist per-entry cache lives ([#65](#65)) ([5bcd077](5bcd077))

### Continuous Integration

* lint the PR title, and match the analyzer's preset to the notes generator ([#71](#71)) ([9ebd026](9ebd026)), closes [#41](#41) [#65](#65)
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 2.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant