feat(orquestra): enforce semver and conventional commits
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Commit and optionally push a completed feature
|
||||
# Commit and optionally push a completed feature using Conventional Commits.
|
||||
# Usage: ./scripts/commit_feature.sh <feature_id>
|
||||
|
||||
set -euo pipefail
|
||||
@@ -16,7 +16,50 @@ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Stage all changes (excluding node_modules, dist, .next, etc.)
|
||||
feature_meta() {
|
||||
python3 - "$FEATURE_ID" <<'PY'
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
fid = sys.argv[1]
|
||||
path = Path('backlog/features.json')
|
||||
commit_type = 'feat'
|
||||
title = 'completed feature'
|
||||
|
||||
if path.exists():
|
||||
data = json.loads(path.read_text(encoding='utf-8'))
|
||||
for feature in data.get('features', []):
|
||||
if str(feature.get('id')) == fid:
|
||||
ftype = str(feature.get('type', 'feature')).lower()
|
||||
commit_type = {
|
||||
'feature': 'feat',
|
||||
'fix': 'fix',
|
||||
'bug': 'fix',
|
||||
'chore': 'chore',
|
||||
}.get(ftype, 'feat')
|
||||
title = feature.get('title') or feature.get('description') or title
|
||||
break
|
||||
|
||||
subject = re.sub(r'\s+', ' ', str(title)).strip()
|
||||
subject = subject[0].lower() + subject[1:] if subject else 'completed feature'
|
||||
subject = subject.rstrip('.')
|
||||
print(commit_type)
|
||||
print(subject[:120])
|
||||
PY
|
||||
}
|
||||
|
||||
mapfile -t META < <(feature_meta)
|
||||
COMMIT_TYPE="${META[0]:-feat}"
|
||||
COMMIT_SUBJECT="${META[1]:-completed feature}"
|
||||
SCOPE=$(printf '%s' "$FEATURE_ID" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._/-' '-')
|
||||
COMMIT_MSG="$COMMIT_TYPE($SCOPE): $COMMIT_SUBJECT"
|
||||
|
||||
# Validate before touching git state.
|
||||
python3 scripts/validate_conventional_commit.py --message "$COMMIT_MSG"
|
||||
|
||||
# Stage all changes (excluding node_modules, dist, .next, etc. via .gitignore)
|
||||
git add -A
|
||||
|
||||
# Check if there are changes to commit
|
||||
@@ -25,24 +68,10 @@ if git diff --cached --quiet; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create commit message
|
||||
COMMIT_MSG="feat($FEATURE_ID): completed feature"
|
||||
|
||||
# Check if there's a description in the feature
|
||||
if [ -f "work/current.md" ]; then
|
||||
# Extract first line of description if available
|
||||
DESC=$(grep -m1 "^## Description" work/current.md -A1 2>/dev/null | tail -1 | sed 's/^[[:space:]]*//' || true)
|
||||
if [ -n "$DESC" ]; then
|
||||
COMMIT_MSG="$COMMIT_MSG
|
||||
|
||||
$DESC"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Commit
|
||||
git commit -m "$COMMIT_MSG"
|
||||
|
||||
echo "[OK] Committed $FEATURE_ID"
|
||||
echo "[OK] Committed $FEATURE_ID: $COMMIT_MSG"
|
||||
|
||||
# Check if remote exists and push
|
||||
if git remote get-url origin >/dev/null 2>&1; then
|
||||
|
||||
Reference in New Issue
Block a user