| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- #!/usr/bin/env bash
- # land-branch.sh — solo-git integrate gate for the 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"
|