feat: add conventional commit message validation
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
|||||||
commitFiles,
|
commitFiles,
|
||||||
push,
|
push,
|
||||||
getDiff,
|
getDiff,
|
||||||
|
validateCommitMessage,
|
||||||
} from "../services/git.service.js";
|
} from "../services/git.service.js";
|
||||||
import type { RepoName } from "../config/repos.js";
|
import type { RepoName } from "../config/repos.js";
|
||||||
|
|
||||||
@@ -88,6 +89,12 @@ router.post("/:repo/commit", async (req, res) => {
|
|||||||
if (body) fullMessage += `\n\n${body}`;
|
if (body) fullMessage += `\n\n${body}`;
|
||||||
if (issueRef) fullMessage += `\n\nFixes #${issueRef}`;
|
if (issueRef) fullMessage += `\n\nFixes #${issueRef}`;
|
||||||
|
|
||||||
|
const validation = validateCommitMessage(fullMessage);
|
||||||
|
if (!validation.valid) {
|
||||||
|
res.status(400).json({ error: validation.error });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const repoPath = getRepoPath(repoName);
|
const repoPath = getRepoPath(repoName);
|
||||||
const result = await commitFiles(repoPath, fullMessage, files);
|
const result = await commitFiles(repoPath, fullMessage, files);
|
||||||
res.json(result);
|
res.json(result);
|
||||||
|
|||||||
@@ -52,7 +52,25 @@ export async function pull(repoPath: string) {
|
|||||||
return g.pull();
|
return g.pull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const COMMIT_PATTERN = /^(feat|fix|refactor|docs|chore|test|style|perf|ci|build|revert)(\(.+\))?: .{1,100}$/;
|
||||||
|
|
||||||
|
export function validateCommitMessage(message: string): { valid: boolean; error?: string } {
|
||||||
|
const firstLine = message.split("\n")[0];
|
||||||
|
if (!COMMIT_PATTERN.test(firstLine)) {
|
||||||
|
return {
|
||||||
|
valid: false,
|
||||||
|
error: `Invalid format. Expected: type(scope): description. Valid types: feat, fix, refactor, docs, chore, test, style, perf, ci, build, revert`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { valid: true };
|
||||||
|
}
|
||||||
|
|
||||||
export async function commitFiles(repoPath: string, message: string, files?: string[]) {
|
export async function commitFiles(repoPath: string, message: string, files?: string[]) {
|
||||||
|
const validation = validateCommitMessage(message);
|
||||||
|
if (!validation.valid) {
|
||||||
|
throw new Error(validation.error);
|
||||||
|
}
|
||||||
|
|
||||||
const g = git(repoPath);
|
const g = git(repoPath);
|
||||||
if (files && files.length > 0) {
|
if (files && files.length > 0) {
|
||||||
await g.add(files);
|
await g.add(files);
|
||||||
|
|||||||
Reference in New Issue
Block a user