Skip to content

Commit 9b629c6

Browse files
authored
chore: add pre-commit hook for conventional commit verification (#619)
1 parent 95d3e3f commit 9b629c6

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

.githooks/commit-msg

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/sh
2+
# Verify commit message follows conventional commit format
3+
# https://www.conventionalcommits.org/
4+
#
5+
# Uses npx commitlint if Node.js is available (same as CI),
6+
# otherwise falls back to basic shell regex validation.
7+
8+
commit_msg_file="$1"
9+
commit_msg=$(cat "$commit_msg_file")
10+
11+
# Skip merge commits
12+
if echo "$commit_msg" | grep -qE "^Merge "; then
13+
exit 0
14+
fi
15+
16+
# Try to use commitlint via npx if Node.js is available
17+
if command -v npx >/dev/null 2>&1; then
18+
# Run commitlint with config-conventional rules (same as CI)
19+
echo "$commit_msg" | npx --yes @commitlint/cli@latest --extends @commitlint/config-conventional
20+
exit $?
21+
fi
22+
23+
# Fallback: basic shell regex validation if Node.js is not available
24+
echo "Note: Node.js not found, using basic commit message validation."
25+
echo " Install Node.js for full commitlint validation (same as CI)."
26+
echo ""
27+
28+
# Conventional commit types from @commitlint/config-conventional
29+
types="build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test"
30+
31+
# Pattern: type(optional-scope): description
32+
# The description must start with lowercase and not end with period
33+
pattern="^($types)(\(.+\))?(!)?: .+"
34+
35+
if ! echo "$commit_msg" | head -1 | grep -qE "$pattern"; then
36+
echo "ERROR: Commit message does not follow conventional commit format."
37+
echo ""
38+
echo "Expected format: <type>(<scope>): <description>"
39+
echo ""
40+
echo "Valid types: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test"
41+
echo ""
42+
echo "Examples:"
43+
echo " feat: add new feature"
44+
echo " fix(parser): resolve parsing issue"
45+
echo " docs: update README"
46+
echo ""
47+
echo "Your commit message:"
48+
echo " $(head -1 "$commit_msg_file")"
49+
exit 1
50+
fi

crates/rmcp/build.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Install git hooks on build
2+
fn main() {
3+
// Only run in the workspace root (not when building as a dependency)
4+
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
5+
let workspace_root = std::path::Path::new(&manifest_dir)
6+
.parent()
7+
.and_then(|p| p.parent());
8+
9+
if let Some(root) = workspace_root {
10+
let githooks_dir = root.join(".githooks");
11+
let git_dir = root.join(".git");
12+
13+
// Only configure if we're in the actual workspace (not a dependency)
14+
// and git directory exists
15+
if githooks_dir.exists() && git_dir.exists() {
16+
// Configure git to use our hooks directory
17+
let _ = std::process::Command::new("git")
18+
.args(["config", "core.hooksPath", ".githooks"])
19+
.current_dir(root)
20+
.output();
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)