feat: 融合 devflow-claude P0 批机制 (REQ-20260416-0017)
P0-1: SessionStart Hook — hooks/session-context.sh 从分支名解析 REQ-ID,调 MCP API 查询需求详情注入 system-reminder P0-2: PreToolUse Hook — hooks/pre-tool-confirm.sh 拦截生产推送、force push、docker prod 容器操作、git reset --hard 等 P0-3: Release Draft 闸门设计文档 — docs/design/release-draft-gate.md 完整架构 + 渐进式落地路径(拆 7 个子任务延后) 附最小可用脚本 hooks/release-draft.sh 创建 Gitea draft release P0-4: Memory 隔离规则 — 写入 req-prd / req-design / req-workflow 禁止 auto-memory 污染模板产出物(章节结构、字段定义、文档结构) P0-5: CLAUDE.md 架构检查 + 架构片段库 dev-coding skill 执行前检查架构关键词 新增 templates/claude-md-snippets/ 含 Go+Gin / React+AntD / Vue+Element / MCP+TS / generic 五套骨架 P0-6: /commit 分支保护自动化 — 新 skill dev-commit-plugin 保护分支自动建功能分支 + Conventional Commits + REQ-XXX 自动关联 安装: bash hooks/install.sh 后续: P0-3 完整实现拆 7 个子任务(P0-3.1 ~ P0-3.7) 建议先部署 hooks 跑 1-2 周观察,再推进 Release 机制落地
This commit is contained in:
161
hooks/release-draft.sh
Executable file
161
hooks/release-draft.sh
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/bin/bash
|
||||
# release-draft.sh
|
||||
# 最小可用版:从本地 git 仓库创建 Gitea draft release
|
||||
#
|
||||
# 用法:
|
||||
# export GITEA_TOKEN=$(bw get password "Gitea - qiudl Token")
|
||||
# bash release-draft.sh v1.2.0 [--from v1.1.9]
|
||||
#
|
||||
# 输出: 创建的 draft release URL(待人工 publish)
|
||||
# REQ-20260416-0017 P0-3 最小可用脚本
|
||||
|
||||
set -e
|
||||
|
||||
VERSION="$1"
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "❌ 用法: $0 <version> [--from <previous_tag>]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FROM_TAG=""
|
||||
if [ "$2" = "--from" ]; then
|
||||
FROM_TAG="$3"
|
||||
fi
|
||||
|
||||
if ! git rev-parse --git-dir >/dev/null 2>&1; then
|
||||
echo "❌ 不在 git 仓库内"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REPO_SLUG=$(git remote get-url origin 2>/dev/null | \
|
||||
sed -E 's|.*[:/]([^/]+/[^/]+)\.git$|\1|' | \
|
||||
sed -E 's|.*[:/]([^/]+/[^/]+)$|\1|')
|
||||
|
||||
if [ -z "$REPO_SLUG" ]; then
|
||||
echo "❌ 无法从 git remote 推断 OWNER/REPO"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$GITEA_TOKEN" ]; then
|
||||
echo "❌ 需要 GITEA_TOKEN 环境变量"
|
||||
echo " export GITEA_TOKEN=\$(bw get password 'Gitea - qiudl Token')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GITEA_URL="${GITEA_URL:-https://gitea.pipexerp.com}"
|
||||
|
||||
# 推断 from
|
||||
if [ -z "$FROM_TAG" ]; then
|
||||
FROM_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
TO_REF="HEAD"
|
||||
|
||||
# 生成 changelog 内容
|
||||
echo "📋 生成 changelog..."
|
||||
|
||||
CHANGELOG=""
|
||||
if [ -n "$FROM_TAG" ]; then
|
||||
COMMITS=$(git log --pretty=format:'- %s (%h)' "${FROM_TAG}..${TO_REF}" 2>/dev/null || echo "")
|
||||
else
|
||||
COMMITS=$(git log --pretty=format:'- %s (%h)' "${TO_REF}" 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if [ -z "$COMMITS" ]; then
|
||||
echo "⚠️ 无 commit,放弃"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 按类型分组
|
||||
FEATS=$(echo "$COMMITS" | grep -iE 'feat(\(|:)|新功能' || true)
|
||||
FIXES=$(echo "$COMMITS" | grep -iE 'fix(\(|:)|修复' || true)
|
||||
CHORES=$(echo "$COMMITS" | grep -iE 'chore(\(|:)' || true)
|
||||
OTHERS=$(echo "$COMMITS" | grep -vE 'feat(\(|:)|fix(\(|:)|chore(\(|:)|新功能|修复' || true)
|
||||
|
||||
CHANGELOG="## 发布内容
|
||||
|
||||
**版本**: \`${VERSION}\`
|
||||
**区间**: \`${FROM_TAG:-init}..${TO_REF}\`
|
||||
|
||||
"
|
||||
|
||||
if [ -n "$FEATS" ]; then
|
||||
CHANGELOG="${CHANGELOG}### 新功能
|
||||
|
||||
${FEATS}
|
||||
|
||||
"
|
||||
fi
|
||||
|
||||
if [ -n "$FIXES" ]; then
|
||||
CHANGELOG="${CHANGELOG}### Bug 修复
|
||||
|
||||
${FIXES}
|
||||
|
||||
"
|
||||
fi
|
||||
|
||||
if [ -n "$CHORES" ]; then
|
||||
CHANGELOG="${CHANGELOG}### 杂项
|
||||
|
||||
${CHORES}
|
||||
|
||||
"
|
||||
fi
|
||||
|
||||
if [ -n "$OTHERS" ]; then
|
||||
CHANGELOG="${CHANGELOG}### 其他
|
||||
|
||||
${OTHERS}
|
||||
|
||||
"
|
||||
fi
|
||||
|
||||
CHANGELOG="${CHANGELOG}
|
||||
|
||||
---
|
||||
|
||||
⚠️ **这是 draft release**,审查无误后点击 'Publish release' 按钮才会触发生产部署。
|
||||
|
||||
📋 审查要点:
|
||||
- [ ] 所有改动已过 PR 评审
|
||||
- [ ] SQL migration 已验证(如有)
|
||||
- [ ] 回滚方案已确认(如有)
|
||||
- [ ] 生产环境准备就绪"
|
||||
|
||||
# 创建 draft release
|
||||
echo "🚀 创建 Gitea draft release..."
|
||||
|
||||
BODY_JSON=$(python3 -c "
|
||||
import json
|
||||
print(json.dumps({
|
||||
'tag_name': '$VERSION',
|
||||
'target_commitish': 'main',
|
||||
'name': '$VERSION',
|
||||
'body': '''$CHANGELOG''',
|
||||
'draft': True,
|
||||
'prerelease': False,
|
||||
}))
|
||||
")
|
||||
|
||||
RESP=$(curl -s -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$BODY_JSON" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO_SLUG}/releases")
|
||||
|
||||
HTML_URL=$(echo "$RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('html_url',''))" 2>/dev/null)
|
||||
|
||||
if [ -n "$HTML_URL" ]; then
|
||||
echo "✅ Draft release 已创建"
|
||||
echo "🔗 $HTML_URL"
|
||||
echo ""
|
||||
echo "⏭️ 下一步:"
|
||||
echo " 1. 打开链接审查产物清单"
|
||||
echo " 2. 确认无误后点 'Publish release' 按钮"
|
||||
echo " 3. CI/CD 将自动触发生产部署"
|
||||
else
|
||||
echo "❌ 创建失败"
|
||||
echo "$RESP" | head -20
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user