Browse Source

feat(workflow): add land-branch.sh for solo-git integrate gate

Alexander Korolev 2 months ago
parent
commit
84f4cb456a
1 changed files with 80 additions and 0 deletions
  1. 80 0
      scripts/land-branch.sh

+ 80 - 0
scripts/land-branch.sh

@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+# land-branch.sh — solo-git integrate gate for sm121-launcher.
+#
+# Usage:
+#   bash scripts/land-branch.sh "<conventional-commit-message>"
+#
+# Runs all quality gates, blocks AI-attribution footers, commits staged
+# changes onto the current branch, and pushes to origin.
+#
+# Designed for the solo-git workflow (workflow_mode: solo-git in
+# specs/state.yaml). When work is on a feature branch, the caller is
+# expected to have already squash-merged onto main (or run from main
+# directly with staged changes).
+#
+# Exit codes:
+#   0 — landed successfully
+#   1 — gates failed, commit blocked, or push rejected
+
+set -euo pipefail
+
+cd "$(dirname "$0")/.."
+
+if [ -t 2 ]; then
+    RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m'; RESET=$'\033[0m'
+else
+    RED=""; GREEN=""; YELLOW=""; RESET=""
+fi
+
+step() { printf '%s==> %s%s\n' "$YELLOW" "$*" "$RESET" >&2; }
+ok()   { printf '%s  ✓ %s%s\n' "$GREEN"  "$*" "$RESET" >&2; }
+die()  { printf '%s  ✗ %s%s\n' "$RED"    "$*" "$RESET" >&2; exit 1; }
+
+# ── Args ──────────────────────────────────────────────────────────────
+if [ "$#" -lt 1 ]; then
+    echo "Usage: $0 \"<conventional-commit-message>\"" >&2
+    exit 1
+fi
+COMMIT_MSG="$1"
+
+# ── 1. Quality gates ──────────────────────────────────────────────────
+step "Running quality gates (make check)"
+if ! make check; then
+    die "Quality gates failed — commit aborted"
+fi
+ok "gates passed"
+
+# ── 2. Conventional Commit check ───────────────────────────────────────
+step "Verifying conventional commit format"
+if ! echo "$COMMIT_MSG" | grep -qE '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .+$'; then
+    die "Commit message does not follow Conventional Commits: $COMMIT_MSG"
+fi
+ok "commit message is conventional"
+
+# ── 3. Block AI attribution ────────────────────────────────────────────
+step "Checking for AI attribution footers"
+if echo "$COMMIT_MSG" | grep -qiE 'co[- ]authored[- ]by'; then
+    die "Co-authored-by footer detected — blocked by P1 rule (CONVENTIONS.md § Git Attribution)"
+fi
+ok "no AI attribution"
+
+# ── 4. Commit staged changes ───────────────────────────────────────────
+step "Committing staged changes"
+if ! git diff --cached --quiet; then
+    git commit -m "$COMMIT_MSG"
+    ok "changes committed"
+else
+    echo "  (no staged changes to commit)"
+fi
+
+# ── 5. Push ───────────────────────────────────────────────────────────
+step "Pushing to origin"
+BRANCH=$(git symbolic-ref --short HEAD)
+if git push origin "$BRANCH"; then
+    ok "pushed to origin/$BRANCH"
+else
+    die "push failed — check for remote divergence"
+fi
+
+echo
+printf '%sLanded: %s%s\n' "$GREEN" "$COMMIT_MSG" "$RESET"