Instruction file imported from xability/maidr (
.github/instructions/git-workflow.instructions.md). Copyright stays with the author.
Git workflow
Releases are automated by semantic-release from main, so commit messages are
the release input, not just a log. Commitlint runs on commit-msg via Husky and
rejects anything that does not parse.
Commit messages
Conventional Commits (@commitlint/config-conventional):
<type>(<optional scope>): <description>
Types: feat, fix, perf, refactor, docs, style, test, build,
ci, chore, revert.
Version impact:
feat:→ minor releasefix:/perf:→ patch releaseBREAKING CHANGE:in the footer, or!after the type → major release- everything else → no release
Write the description in the imperative mood, lower case, no trailing period:
fix(audio): resume suspended context before playing empty-state tones.
! works because .releaserc.json hands both commit-parsing plugins a
parserOpts that admits it. Without that they use the default angular
patterns, which do not, and a !-marked subject then fails to parse
entirely: no type, no matching release rule, no release at all, and the
commit missing from the notes as well. commitlint accepts ! either way, so
nothing upstream of the release would have flagged it. Leave the
parserOpts alone unless you intend that; test/scripts/releaseBreakingMarker.esm-test.ts
fails if either plugin loses them.
Squashed merges compose the release commit from the pull request title, so a
breaking change needs its ! in the title, not only in a commit inside
the branch.
Practice
- One logical change per commit. Split unrelated fixes rather than bundling them.
- Never commit to
maindirectly; work on a branch. - Run
npm run lint:fix,npm run type-check, and the relevant tests before committing. - Do not hand-edit
CHANGELOG.mdor theversionfield inpackage.json— semantic-release owns both.