config(git): 引入develop长期开发分支模型和git工作流自动化
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
#!/usr/bin/env bash
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# git-workflow.sh — ChildHood 项目 Git 工作流自动化
|
||||
#
|
||||
# 基于 develop 长期开发分支模型。
|
||||
# 所有 agent 在 develop 上工作,迭代结束时通过 PR 合并回 main。
|
||||
#
|
||||
# 用法: bash .claude/scripts/git-workflow.sh <command> [args...]
|
||||
#
|
||||
# 命令:
|
||||
# ready 确保在 develop 上且最新
|
||||
# commit <type> <scope> "<msg>" 格式化提交
|
||||
# push 推送 develop 到远程
|
||||
# submit <issue-number> 一键 commit + push(从 Issue 拉取信息)
|
||||
# release [milestone-name] 创建 develop→main 的 PR
|
||||
# post-release 合并后同步 main 和 develop
|
||||
# catchup 将 develop 合并最新 main 的内容
|
||||
# status 显示当前分支和状态
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── 配置 ───
|
||||
DEVELOP_BRANCH="develop"
|
||||
MAIN_BRANCH="main"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
GITEA_PM_CLI="node $PROJECT_ROOT/.claude/skills/gitea-pm/gitea.js"
|
||||
GITEA_COLLAB_CLI="node $PROJECT_ROOT/.claude/skills/gitea-collab/gitea.js"
|
||||
|
||||
# ─── 颜色 ───
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
info() { echo -e "${BLUE}ℹ️ $*${NC}"; }
|
||||
ok() { echo -e "${GREEN}✅ $*${NC}"; }
|
||||
warn() { echo -e "${YELLOW}⚠️ $*${NC}"; }
|
||||
fail() { echo -e "${RED}❌ $*${NC}"; exit 1; }
|
||||
|
||||
# ─── 当前分支 ───
|
||||
current_branch() { git rev-parse --abbrev-ref HEAD; }
|
||||
|
||||
# ─── 检查是否有未提交的修改 ───
|
||||
has_changes() { [ -n "$(git status --porcelain)" ]; }
|
||||
|
||||
# ─── 检测 UE5 二进制文件 ───
|
||||
has_ue5_binaries() {
|
||||
git diff --cached --name-only 2>/dev/null | grep -qE '\.(uasset|umap)$'
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# 命令实现
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
cmd_ready() {
|
||||
info "准备工作环境..."
|
||||
|
||||
local branch
|
||||
branch=$(current_branch)
|
||||
|
||||
# 如果不在 develop 上,切换过去
|
||||
if [ "$branch" != "$DEVELOP_BRANCH" ]; then
|
||||
if has_changes; then
|
||||
warn "有未提交的修改,暂存中..."
|
||||
git stash push --include-untracked -m "auto-stash-$(date +%s)"
|
||||
fi
|
||||
git checkout "$DEVELOP_BRANCH" 2>/dev/null || {
|
||||
# 本地没有 develop 分支,从 main 创建
|
||||
info "本地没有 $DEVELOP_BRANCH 分支,从 $MAIN_BRANCH 创建..."
|
||||
git checkout "$MAIN_BRANCH"
|
||||
git pull origin "$MAIN_BRANCH"
|
||||
git checkout -b "$DEVELOP_BRANCH"
|
||||
}
|
||||
fi
|
||||
|
||||
# 拉取最新 develop
|
||||
if git remote get-url origin &>/dev/null; then
|
||||
info "拉取远程 $DEVELOP_BRANCH..."
|
||||
git pull origin "$DEVELOP_BRANCH" 2>/dev/null || {
|
||||
# 远程没有 develop,首次推送
|
||||
warn "远程没有 $DEVELOP_BRANCH 分支,将首次推送"
|
||||
}
|
||||
fi
|
||||
|
||||
local commit_hash
|
||||
commit_hash=$(git rev-parse --short HEAD)
|
||||
ok "已在 $DEVELOP_BRANCH 分支上 (${commit_hash})"
|
||||
}
|
||||
|
||||
cmd_commit() {
|
||||
local type="${1:-}"
|
||||
local scope="${2:-}"
|
||||
local message="${3:-}"
|
||||
|
||||
if [ -z "$type" ] || [ -z "$scope" ] || [ -z "$message" ]; then
|
||||
fail "用法: git-workflow.sh commit <type> <scope> \"<message>\"\n 示例: git-workflow.sh commit feat player \"实现角色跳跃\""
|
||||
fi
|
||||
|
||||
# 校验分支
|
||||
if [ "$(current_branch)" != "$DEVELOP_BRANCH" ]; then
|
||||
warn "当前不在 $DEVELOP_BRANCH 分支上 (当前: $(current_branch))"
|
||||
read -rp "继续提交? [y/N] " confirm
|
||||
[[ "$confirm" != [yY] ]] && { info "已取消"; return; }
|
||||
fi
|
||||
|
||||
# 暂存所有修改
|
||||
if ! has_changes; then
|
||||
warn "没有检测到修改"
|
||||
return
|
||||
fi
|
||||
|
||||
git add -A
|
||||
|
||||
# UE5 二进制文件检测
|
||||
if has_ue5_binaries; then
|
||||
warn "检测到 .uasset/.umap 文件,请确保 commit message 清楚描述了变更内容"
|
||||
fi
|
||||
|
||||
# 格式化 commit message
|
||||
local commit_msg="${type}(${scope}): ${message}"
|
||||
|
||||
# subject ≤ 50 字符检查(仅消息部分)
|
||||
local msg_len=${#commit_msg}
|
||||
if [ "$msg_len" -gt 72 ]; then
|
||||
warn "提交消息较长 ($msg_len 字符),建议精简"
|
||||
fi
|
||||
|
||||
git commit -m "$commit_msg"
|
||||
ok "已提交: $commit_msg"
|
||||
}
|
||||
|
||||
cmd_push() {
|
||||
local branch
|
||||
branch=$(current_branch)
|
||||
|
||||
info "推送 $branch 到远程..."
|
||||
|
||||
# 设置上游分支(首次)
|
||||
if ! git rev-parse --abbrev-ref "@{upstream}" &>/dev/null; then
|
||||
git push -u origin "$branch"
|
||||
else
|
||||
git push origin "$branch"
|
||||
fi
|
||||
|
||||
ok "已推送 $branch 到远程"
|
||||
}
|
||||
|
||||
cmd_submit() {
|
||||
local issue_number="${1:-}"
|
||||
if [ -z "$issue_number" ]; then
|
||||
fail "用法: git-workflow.sh submit <issue-number>"
|
||||
fi
|
||||
|
||||
info "提交工作 (Issue #$issue_number)..."
|
||||
|
||||
# 从 Issue 拉取标题作为 commit 参考
|
||||
local issue_title=""
|
||||
issue_title=$($GITEA_COLLAB_CLI --role dev issue get "$issue_number" --json 2>/dev/null | grep -o '"title":"[^"]*"' | head -1 | sed 's/"title":"//;s/"//') || true
|
||||
|
||||
# 提交
|
||||
if has_changes; then
|
||||
if [ -n "$issue_title" ]; then
|
||||
info "Issue 标题: $issue_title"
|
||||
fi
|
||||
warn "有未提交的修改,请先运行: git-workflow.sh commit <type> <scope> \"<message>\""
|
||||
return
|
||||
fi
|
||||
|
||||
# 推送
|
||||
cmd_push
|
||||
|
||||
ok "工作已提交到 $DEVELOP_BRANCH (关联 Issue #$issue_number)"
|
||||
}
|
||||
|
||||
cmd_release() {
|
||||
local milestone_name="${1:-}"
|
||||
|
||||
info "准备发布 PR ($DEVELOP_BRANCH → $MAIN_BRANCH)..."
|
||||
|
||||
# 确保在 develop 上
|
||||
if [ "$(current_branch)" != "$DEVELOP_BRANCH" ]; then
|
||||
fail "请先切换到 $DEVELOP_BRANCH 分支"
|
||||
fi
|
||||
|
||||
# 确保本地最新
|
||||
git pull origin "$DEVELOP_BRANCH"
|
||||
|
||||
# 获取里程碑名称
|
||||
if [ -z "$milestone_name" ]; then
|
||||
# 尝试从当前里程碑获取
|
||||
milestone_name=$($GITEA_PM_CLI --role pm milestone list --state open --json 2>/dev/null | grep -o '"title":"[^"]*"' | head -1 | sed 's/"title":"//;s/"//') || "迭代发布"
|
||||
if [ -z "$milestone_name" ]; then
|
||||
milestone_name="迭代发布"
|
||||
fi
|
||||
fi
|
||||
|
||||
local pr_title="Merge develop → main: ${milestone_name}"
|
||||
|
||||
# 构造 PR body(汇总已关闭的 Issue)
|
||||
local pr_body="## 发布合并\n\n将 \`${DEVELOP_BRANCH}\` 分支的成果合并到 \`${MAIN_BRANCH}\`。\n\n### 里程碑\n${milestone_name}"
|
||||
|
||||
# 创建 PR
|
||||
info "创建 PR: $pr_title"
|
||||
local pr_result
|
||||
pr_result=$($GITEA_PM_CLI --role pm pr create \
|
||||
--base "$MAIN_BRANCH" \
|
||||
--head "$DEVELOP_BRANCH" \
|
||||
--title "$pr_title" \
|
||||
--body "$(echo -e "$pr_body")" \
|
||||
--json 2>&1) || {
|
||||
fail "创建 PR 失败: $pr_result"
|
||||
}
|
||||
|
||||
local pr_number
|
||||
pr_number=$(echo "$pr_result" | grep -o '"number":[0-9]*' | head -1 | sed 's/"number"://') || true
|
||||
|
||||
if [ -n "$pr_number" ]; then
|
||||
ok "PR #$pr_number 已创建: $pr_title"
|
||||
info "请在 Gitea 审查并合并: http://micecola.top:8418/starmen1265/ChildHood/pulls/$pr_number"
|
||||
else
|
||||
ok "PR 已创建,请查看 Gitea"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_post_release() {
|
||||
info "合并后同步..."
|
||||
|
||||
# 同步 main
|
||||
info "同步 $MAIN_BRANCH..."
|
||||
git checkout "$MAIN_BRANCH"
|
||||
git pull origin "$MAIN_BRANCH"
|
||||
ok "$MAIN_BRANCH 已更新"
|
||||
|
||||
# 切回 develop 并合并 main(保持 develop 包含 merge commit)
|
||||
info "同步 $DEVELOP_BRANCH..."
|
||||
git checkout "$DEVELOP_BRANCH"
|
||||
git merge "$MAIN_BRANCH" --no-edit
|
||||
git push origin "$DEVELOP_BRANCH"
|
||||
ok "$DEVELOP_BRANCH 已同步(包含 $MAIN_BRANCH 的 merge commit)"
|
||||
|
||||
local commit_hash
|
||||
commit_hash=$(git rev-parse --short HEAD)
|
||||
ok "完成,当前在 $DEVELOP_BRANCH (${commit_hash})"
|
||||
}
|
||||
|
||||
cmd_catchup() {
|
||||
info "将 develop 跟上最新的 $MAIN_BRANCH..."
|
||||
|
||||
if [ "$(current_branch)" != "$DEVELOP_BRANCH" ]; then
|
||||
fail "请先切换到 $DEVELOP_BRANCH 分支"
|
||||
fi
|
||||
|
||||
git fetch origin
|
||||
git merge "origin/$MAIN_BRANCH" --no-edit
|
||||
ok "$DEVELOP_BRANCH 已合并最新 $MAIN_BRANCH"
|
||||
}
|
||||
|
||||
cmd_status() {
|
||||
local branch
|
||||
branch=$(current_branch)
|
||||
local commit_hash
|
||||
commit_hash=$(git rev-parse --short HEAD)
|
||||
local changed
|
||||
changed=$(git status --porcelain | wc -l | tr -d ' ')
|
||||
|
||||
echo -e "${BLUE}═══ Git 工作流状态 ═══${NC}"
|
||||
echo " 当前分支: ${branch} (${commit_hash})"
|
||||
|
||||
if [ "$branch" = "$DEVELOP_BRANCH" ]; then
|
||||
echo -e " ${GREEN}✓ 在 develop 开发分支上${NC}"
|
||||
elif [ "$branch" = "$MAIN_BRANCH" ]; then
|
||||
echo -e " ${YELLOW}⚠ 在 main 分支上,请切换到 develop 开始工作${NC}"
|
||||
else
|
||||
echo -e " ${YELLOW}⚠ 在非标准分支上: $branch${NC}"
|
||||
fi
|
||||
|
||||
echo " 未提交修改: ${changed} 个文件"
|
||||
|
||||
if [ "$changed" -gt 0 ]; then
|
||||
echo ""
|
||||
git status --short
|
||||
fi
|
||||
|
||||
# 远程同步状态
|
||||
if git rev-parse "@{upstream}" &>/dev/null; then
|
||||
local ahead behind
|
||||
ahead=$(git rev-list --count "@{upstream}..HEAD" 2>/dev/null || echo "0")
|
||||
behind=$(git rev-list --count "HEAD..@{upstream}" 2>/dev/null || echo "0")
|
||||
echo " 远程状态: ahead ${ahead}, behind ${behind}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# 入口
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
case "${1:-}" in
|
||||
ready) cmd_ready ;;
|
||||
commit) shift; cmd_commit "$@" ;;
|
||||
push) cmd_push ;;
|
||||
submit) shift; cmd_submit "$@" ;;
|
||||
release) shift; cmd_release "$@" ;;
|
||||
post-release) cmd_post_release ;;
|
||||
catchup) cmd_catchup ;;
|
||||
status) cmd_status ;;
|
||||
*)
|
||||
echo "git-workflow.sh — ChildHood 项目 Git 工作流自动化"
|
||||
echo ""
|
||||
echo "用法: bash .claude/scripts/git-workflow.sh <command> [args...]"
|
||||
echo ""
|
||||
echo "命令:"
|
||||
echo " ready 确保在 develop 上且最新"
|
||||
echo " commit <type> <scope> \"<msg>\" 格式化提交"
|
||||
echo " push 推送 develop 到远程"
|
||||
echo " submit <issue-number> 推送并关联 Issue"
|
||||
echo " release [milestone-name] 创建 develop→main PR"
|
||||
echo " post-release 合并后同步 main 和 develop"
|
||||
echo " catchup 将 develop 合并最新 main"
|
||||
echo " status 显示当前分支和状态"
|
||||
echo ""
|
||||
echo "工作流模型: develop 长期开发分支 → 迭代完成时 PR 合并回 main"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user