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
2 changes: 1 addition & 1 deletion ai/rules.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ See [Coding Styleguide Shell Scripts](./coding-styleguide-sh.mdc)
- Prefer staged validation for non-trivial tasks. While iterating, run only fast, focused checks (type diagnostics, the single affected unit test file). Defer slow checks (browser/e2e/visual tests, builds, full test suites) until the change is complete, unless the change touches exactly what that check proves. Run formatting and linting once the change is complete (before handoff, a commit or a push, whoever does it), not after every edit. For trivial tasks, a single final validation is acceptable.
- Adjust documentation both in comments and markdown files once you're done
- Use [Conventional Commits](https://www.conventionalcommits.org/) for commit messages
- **Important**: For breaking changes, do not rely on the `!` shorthand (e.g. `feat!:`). This repo's semantic-release config uses the default `conventional-changelog-angular` preset, whose header parser does not recognize `!` — such commits are silently ignored (not even counted as a `feat`/`fix` release). Always add a `BREAKING CHANGE:` footer describing the change instead.
- For breaking changes, mark the commit or PR title with `!` (e.g. `feat(scope)!:`) and add a `BREAKING CHANGE:` footer that tells consumers what to do. `@peerigon/configs/semantic-release` uses the `conventionalcommits` preset, which honors `!`. If a project still uses the default `angular` preset, `!` is ignored and the `BREAKING CHANGE:` paragraph (at the start of a line, not a heading) is the only trigger, otherwise the merge releases nothing.

## Consumer-repo uncertainty protocol

Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"@tanstack/eslint-plugin-query": "^5.101.4",
"@types/eslint-config-prettier": "^6.11.3",
"@vitest/eslint-plugin": "^1.6.23",
"conventional-changelog-conventionalcommits": "^9.3.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-i18next": "^6.1.5",
"eslint-plugin-jsx-a11y-x": "^0.2.0",
Expand Down
30 changes: 30 additions & 0 deletions semantic-release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,33 @@ with branch protection rules.
To prevent stale changelogs, releases fail when a `CHANGELOG.md` file exists in the
repository. You can bypass this check by setting
`SEMANTIC_RELEASE_ALLOW_CHANGELOG=true`.

## Commit analysis: `conventionalcommits` preset

The preset uses the `conventionalcommits` preset for both the commit analyzer and the release notes
generator instead of semantic-release's default `angular` preset. The only functional difference for
releases is the `!` shorthand:

| Commit message | `angular` (default) | `conventionalcommits` |
| ---------------------------------------------------- | ------------------- | --------------------- |
| `feat(scope)!: drop Node 20` | **no release** | major |
| `fix!: change default` | **no release** | major |
| `feat: x` + footer `BREAKING CHANGE: ...` | major | major |
| `feat!: x` + footer `BREAKING-CHANGE: ...` | **no release** | major |
| `feat: x` + heading `## BREAKING CHANGE` in the body | minor | minor |
| `fix: x` / `perf: x` | patch | patch |
| `refactor:`, `docs:`, `chore:`, `build:`, `ci:` | no release | no release |

Note that a heading like `## BREAKING CHANGE` never counts. The footer has to be a paragraph that starts
with `BREAKING CHANGE:` at the beginning of a line. Because squash merges use the PR title as the commit
header and the PR description as the body, this applies to PR titles and descriptions as well.

The release notes also look different:

- `BREAKING CHANGES` is rendered as `### ⚠ BREAKING CHANGES` and listed first, including `!` commits
(`* **x:** drop Node 20`). With `angular`, only commits with a footer show up there.
- Section order is Features, Bug Fixes, Performance Improvements, Reverts (`angular`: Bug Fixes first).
- The version header is `## [2.0.0]` (`angular`: `# [2.0.0]` for minor/major and `## [2.0.0]` for patches).

Still add a `BREAKING CHANGE:` footer to every breaking change: it carries the migration instructions that
end up in the release notes. Projects with their own `.releaserc` that keep the `angular` preset ignore `!`.
6 changes: 4 additions & 2 deletions semantic-release/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ export const config = {
` && node "${verifyPublishableScript}"`,
},
],
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
// The default angular preset ignores the `!` in `feat(scope)!:` and would silently skip
// the release unless the body has a `BREAKING CHANGE:` footer. conventionalcommits honors both.
["@semantic-release/commit-analyzer", { preset: "conventionalcommits" }],
["@semantic-release/release-notes-generator", { preset: "conventionalcommits" }],
[
"@semantic-release/npm",
{
Expand Down
Loading