mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-06 10:39:59 +02:00
## Summary - Enforce **Conventional Commits** on PR titles (PRs are squash-merged, so the PR title becomes the final commit message). - Add a local `make lint-pr-title` target so contributors can validate titles before pushing. ## Why We squash-merge PRs, which means the final repository history is largely shaped by **PR titles**. Enforcing a consistent Conventional Commits format makes: - **Release notes & changelogs easier to generate** (types like `feat` / `fix` can be grouped automatically). - **History easier to scan** (uniform structure, optional scopes, explicit breaking changes via `!`). - **Automation more reliable** (future tooling can infer category and scope from the title). ## PR title format ```text type(scope)!: subject type: one of build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test scope: optional (e.g. web, api, actions, repo, …) !: optional, indicates a breaking change subject: short, imperative, no trailing period ``` ## Examples ```text feat(web): add dark mode toggle fix(api): avoid panic when repo is missing chore(ci): lint PR titles with commitlint refactor(templates): reduce duplication in repo list rendering feat!: remove legacy OAuth endpoint ``` ## Local testing ```text make deps-frontend make lint-pr-title PR_TITLE="feat(web): add dark mode toggle" ``` --------- Signed-off-by: Nicolas <bircni@icloud.com> Co-authored-by: nb <nb@users.noreply.local> Co-authored-by: GPT-5.2 <gpt-5.2@openai.com>
20 lines
559 B
JavaScript
20 lines
559 B
JavaScript
#!/usr/bin/env node
|
|
import {env, exit} from 'node:process';
|
|
|
|
const allowedTypes = 'build, ci, docs, feat, fix, perf, refactor, revert, style, test';
|
|
const title = env.PR_TITLE;
|
|
|
|
if (!title) {
|
|
console.error('Missing PR_TITLE');
|
|
exit(1);
|
|
}
|
|
|
|
const validTitlePattern = new RegExp(`^(${allowedTypes.replaceAll(', ', '|')})(\\([\\w.-]+\\))?(!)?: .+$`);
|
|
|
|
if (!validTitlePattern.test(title)) {
|
|
console.error(`Invalid PR title: ${title}`);
|
|
console.error('Expected format: type(scope): subject');
|
|
console.error(`Allowed types: ${allowedTypes}`);
|
|
exit(1);
|
|
}
|