Code Review and Commit Conventions
A practical guide to effective code review culture, Conventional Commits, and semantic versioning
Contents
Commit conventions make automated versioning possible; code review makes bug prevention and knowledge sharing possible.
Code review and commit conventions are the practices that determine a team's code quality and collaboration efficiency. A systematic commit message convention enables automated versioning and releases. Effective code review prevents bugs before they ship and raises the technical level of the team. As of 2026, AI-based code review tools are spreading quickly and reshaping review culture along with them.
Conventional Commits
Specification
Conventional Commits is a specification that imposes a structured format on commit messages. It lets automated tooling analyze commit history and handle versioning, changelogs, and releases without human input.
Format
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]Commit types
| Type | Description | SemVer impact |
|---|---|---|
feat: | New feature | MINOR bump |
fix: | Bug fix | PATCH bump |
docs: | Documentation change | None |
style: | Code formatting (semicolons, indentation, etc.) | None |
refactor: | Code improvement with no behavior change | None |
perf: | Performance improvement | PATCH bump |
test: | Adding or fixing tests | None |
build: | Build system change (Webpack, npm, etc.) | None |
ci: | CI configuration change | None |
chore: | Other changes (tooling config, package updates, etc.) | None |
revert: | Reverting a previous commit | Depends on the case |
Breaking changes
feat(auth)!: change token format to JWT v5
BREAKING CHANGE: Token format changed from HS256 to ES256.
All existing tokens will be invalidated.
Migration guide: docs/migration/token-v5.md- Append
!after the type, or add aBREAKING CHANGE:footer - Triggers a MAJOR version bump
Real-world examples
# new feature
feat(payment): add cryptocurrency payment support
Implement Bitcoin and Ethereum payment processing
using CoinGate API integration.
Closes #234
# bug fix
fix(auth): resolve JWT refresh token race condition
Multiple concurrent refresh requests could generate
duplicate tokens. Added mutex lock to token refresh handler.
Fixes #567
# refactoring
refactor(order): extract validation logic to separate service
Move order validation from OrderController to
OrderValidationService for better testability and reuse.
# performance
perf(query): optimize user search with database index
Add composite index on (email, created_at) to users table.
Query time reduced from 450ms to 12ms for 1M records.Semantic Versioning (SemVer)
Format
A version has three parts, MAJOR.MINOR.PATCH, and each part indicates the compatibility level of the change.
| Part | Meaning | Trigger | Example 2.4.1 |
|---|---|---|---|
| MAJOR | Backward-incompatible change | BREAKING CHANGE | 2 (second major) |
| MINOR | Backward-compatible feature addition | feat: | 4 (fourth minor) |
| PATCH | Backward-compatible bug fix | fix: | 1 (first patch) |
Bump rules
| Kind of change | Commit type | Version change | Example |
|---|---|---|---|
| Bug fix | fix: | PATCH bump | 1.0.0 -> 1.0.1 |
| New feature | feat: | MINOR bump | 1.0.1 -> 1.1.0 |
| Breaking change | BREAKING CHANGE | MAJOR bump | 1.1.0 -> 2.0.0 |
Pre-release versions
1.0.0-alpha.1 <- alpha
1.0.0-beta.1 <- beta
1.0.0-rc.1 <- release candidate
1.0.0 <- general availabilityVersion ranges in npm and Maven
{
"dependencies": {
"express": "^4.18.0", // 4.x.x (MINOR and PATCH updates allowed)
"lodash": "~4.17.0", // 4.17.x (PATCH updates only)
"react": "18.2.0" // exactly this version
}
}Automated changelogs and releases
semantic-release
A tool that analyzes commit history and decides the version, generates the changelog, and publishes the release automatically.
analyze commit history
|
+-- feat: -> MINOR bump
+-- fix: -> PATCH bump
+-- BREAKING CHANGE -> MAJOR bump
|
v
update version in package.json
|
v
generate CHANGELOG.md
|
v
create Git tag (v2.1.0)
|
v
create GitHub Release
|
v
publish package to npm/PyPI/etc.CI/CD pipeline integration
# GitHub Actions example
name: Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history required
- uses: actions/setup-node@v4
- run: npm ci
- run: npm test
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}Example of a generated CHANGELOG
# Changelog
## [2.1.0] - 2026-02-10
### Features
- **payment**: add cryptocurrency payment support (#234)
- **auth**: implement OAuth 2.1 PKCE flow (#245)
### Bug Fixes
- **auth**: resolve JWT refresh token race condition (#567)
- **order**: fix decimal precision in total calculation (#571)
### Performance
- **query**: optimize user search with database index (#580)Notable tools
| Tool | Language | Characteristics |
|---|---|---|
| semantic-release | Node.js | Most mature, rich plugin ecosystem |
| release-please (Google) | Multi-language | Monorepo support, Release PR model |
| standard-version | Node.js | Manually triggered |
| commitizen | Node.js | Interactive commit message authoring |
| convco | Rust | Fast execution, Conventional Commits validation |
Pre-commit hooks
Definition
A mechanism that runs code checks automatically before a Git commit is created, guaranteeing a baseline of quality.
Husky + lint-staged setup
# install
npm install --save-dev husky lint-staged
# initialize Husky
npx husky init// package.json
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
],
"*.test.{ts,tsx}": [
"jest --bail --findRelatedTests"
]
}
}# .husky/pre-commit
npx lint-stagedcommitlint (commit message validation)
# install
npm install --save-dev @commitlint/cli @commitlint/config-conventional// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'feat', 'fix', 'docs', 'style', 'refactor',
'perf', 'test', 'build', 'ci', 'chore', 'revert'
]],
'subject-max-length': [2, 'always', 72],
'body-max-line-length': [2, 'always', 100]
}
};# .husky/commit-msg
npx --no -- commitlint --edit $1Execution flow
The CODEOWNERS file
Definition
A mechanism that declares code owners per directory or file in a repository so that reviewers are assigned automatically when a PR is opened.
Example configuration
# .github/CODEOWNERS
# global default owners
* @team-lead @senior-dev
# owners per service
/services/auth-service/ @auth-team
/services/payment-service/ @payment-team @security-team
/services/notification/ @platform-team
# infrastructure code
/infrastructure/ @devops-team
/terraform/ @devops-team @security-team
/.github/ @devops-team
# security-sensitive files
/services/*/security/ @security-team
*.env.example @security-team
# shared libraries
/packages/shared-utils/ @platform-team
/packages/api-client/ @api-team
# documentation
/docs/ @tech-writer @team-leadCODEOWNERS best practices
- Assign teams, not people: mention teams rather than individuals (
@org/team-name) - Mandatory review on security files: assign security-team to security-related directories
- Overlapping coverage: have multiple teams review critical areas
- Regular updates: refresh CODEOWNERS whenever team structure changes
- Tie into branch protection: enable "Require review from CODEOWNERS"
Code review best practices
Based on Google's engineering practices
Google's code review guide is the most widely referenced set of practices in the industry.
From the reviewer's side
| Principle | Description |
|---|---|
| Review promptly | Within 24 hours of the PR opening (within hours if possible) |
| Constructive feedback | Point out the problem, propose an alternative, explain why |
| Rank by importance | MUST (blocking), SHOULD (strongly recommended), COULD (optional) |
| Focus on the code | Talk about the code, not the person |
| Understand the context | Read the PR description, linked issues, and design docs |
From the author's side
| Principle | Description |
|---|---|
| Small PRs | 200-400 lines recommended, 800 lines maximum |
| Self-review | Review your own PR once before submitting |
| Adequate explanation | PR title, body, screenshots, test plan |
| Single purpose | One PR, one purpose (do not mix) |
| Tests included | Test code for the change is mandatory |
PR template
## Summary
<!-- summary of the change (1-3 sentences) -->
## Motivation
<!-- why is this change needed? (link the related issue) -->
## Changes
<!-- list of major changes -->
## Test Plan
<!-- how it was tested and the results -->
## Screenshots
<!-- screenshots if the UI changed -->
## ChecklistLevels of review feedback
| Level | Tag | Meaning | Example |
|---|---|---|---|
| Blocker | [MUST] | Cannot merge until resolved | SQL injection vulnerability |
| Major | [SHOULD] | Strongly recommended but open to discussion | Proposing a more efficient algorithm |
| Minor | [COULD] | Optional improvement | Better variable name, added comment |
| Praise | [NICE] | Recognition of well-written code | "This abstraction is very clean" |
| Question | [Q] | Question for understanding | "What is the intent of this logic?" |
AI-based code review (2026 trends)
The current tool landscape
As of 2026, AI-based code review tools are expanding past traditional static analysis toward system-level understanding.
| Tool | Characteristics | Main features |
|---|---|---|
| GitHub Copilot Code Review | GitHub native, automatic PR review | Code quality, security, performance analysis |
| Qodo (formerly CodiumAI) | Test generation plus review | Test coverage analysis, edge case detection |
| CodeRabbit | PR summary plus line-by-line review | Dependency analysis, security vulnerabilities |
| Sourcery | Python-specific | Refactoring suggestions, code quality score |
| CodeAnt AI | Backend API-specific | API contract validation, N+1 query detection |
| Amazon CodeGuru | AWS native | Integrated runtime performance analysis |
What AI review does well, and where it falls short
Strengths
- Automatic bug detection: null pointers, resource leaks, race conditions found automatically
- Security vulnerability scanning: SQL injection, XSS, authentication bypass, and more
- Code quality improvements: suggestions on duplication, complexity, and naming
- Faster reviews: AI handles the mechanical pass so humans concentrate on design and business logic
Limits and cautions
The Veracode 2025 GenAI Code Security Report measured over 100 large language models and found that 45% of AI-generated code failed security tests. CodeRabbit's State of AI vs Human Code Generation Report (2025, analyzing 470 pull requests) found cross-site scripting (XSS) vulnerabilities 2.74 times more often and logic or correctness errors 1.75 times more often than in human-written code.
| Limit | Mitigation |
|---|---|
| Weak grasp of business logic | Human review by a domain expert is mandatory |
| False positives | Configure override rules and use them as training signal |
| Shallow architecture-level analysis | Improving through 2026 (system-aware agents) |
| Incomplete security validation | Run alongside a dedicated security reviewer |
A hybrid AI plus human review strategy
Signed commits
Why signing matters
Git's author and committer fields can be set to anything by anyone. A signed commit cryptographically proves that the commit really was written by that person.
GPG signing
# generate a GPG key
gpg --full-generate-key
# list keys
gpg --list-secret-keys --keyid-format=long
# configure the GPG key in Git
git config --global user.signingkey ABC123DEF456
git config --global commit.gpgsign true
# signed commit
git commit -S -m "feat: add secure payment"
# verify the signature
git log --show-signatureSSH signing (recommended in 2026)
# sign with an SSH key (simpler than GPG)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# signed commit (automatic)
git commit -m "feat: add secure payment"GitHub vigilant mode
A GitHub feature that marks unsigned commits as "Unverified" to flag the possibility of tampering.
The full automation pipeline
The end-to-end flow from commit to release:
Summary
Commit conventions standardize the message format, and that is the starting point for automating version decisions and changelogs. semantic-release and pre-commit hooks wire that format into the build and release pipeline so humans intervene less. Code review assigns accountability through CODEOWNERS and separates feedback into MUST/SHOULD/COULD, aiming at bug prevention and knowledge sharing at the same time. The current practical arrangement gives AI the mechanical pass while humans concentrate on business logic and architecture. Read alongside the branching strategy covered earlier in this series, the path from commit to deployment fits into a single picture.