clawt 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/release.sh +261 -0
package/package.json
CHANGED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================
|
|
3
|
+
# release.sh - Clawt 自动发布脚本
|
|
4
|
+
# 功能: 构建 → 交互式选择版本级别 → 更新 package.json → 提交 → 打 tag → push → npm publish
|
|
5
|
+
# 用法: bash scripts/release.sh
|
|
6
|
+
# ============================================================
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# 颜色定义
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
GREEN='\033[0;32m'
|
|
13
|
+
YELLOW='\033[0;33m'
|
|
14
|
+
CYAN='\033[0;36m'
|
|
15
|
+
BOLD='\033[1m'
|
|
16
|
+
NC='\033[0m' # 恢复默认
|
|
17
|
+
|
|
18
|
+
# ────────────────────────────────────────
|
|
19
|
+
# 工具函数
|
|
20
|
+
# ────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
# 输出成功信息
|
|
23
|
+
print_success() {
|
|
24
|
+
echo -e "${GREEN}✓ $1${NC}"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# 输出错误信息并退出
|
|
28
|
+
print_error() {
|
|
29
|
+
echo -e "${RED}✗ $1${NC}" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# 输出警告信息
|
|
34
|
+
print_warning() {
|
|
35
|
+
echo -e "${YELLOW}⚠ $1${NC}"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# 输出步骤信息
|
|
39
|
+
print_step() {
|
|
40
|
+
echo -e "${CYAN}→ $1${NC}"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# ────────────────────────────────────────
|
|
44
|
+
# 预检
|
|
45
|
+
# ────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
# 确保在项目根目录(有 package.json)
|
|
48
|
+
if [ ! -f "package.json" ]; then
|
|
49
|
+
print_error "请在项目根目录下执行此脚本"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# 确保工作区干净
|
|
53
|
+
if [ -n "$(git status --porcelain)" ]; then
|
|
54
|
+
print_error "工作区有未提交的更改,请先提交或暂存"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# 确保在主分支
|
|
58
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
59
|
+
if [ "$CURRENT_BRANCH" != "main" ] && [ "$CURRENT_BRANCH" != "master" ]; then
|
|
60
|
+
print_warning "当前分支为 ${CURRENT_BRANCH},不是 main/master"
|
|
61
|
+
read -rp "是否继续发布?(y/N) " confirm
|
|
62
|
+
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
|
63
|
+
echo "已取消发布"
|
|
64
|
+
exit 0
|
|
65
|
+
fi
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# ────────────────────────────────────────
|
|
69
|
+
# 读取当前版本
|
|
70
|
+
# ────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
73
|
+
echo ""
|
|
74
|
+
echo -e "${BOLD}当前版本: v${CURRENT_VERSION}${NC}"
|
|
75
|
+
echo ""
|
|
76
|
+
|
|
77
|
+
# ────────────────────────────────────────
|
|
78
|
+
# 解析版本号
|
|
79
|
+
# ────────────────────────────────────────
|
|
80
|
+
|
|
81
|
+
# 将 semver 拆分为 major / minor / patch / prerelease
|
|
82
|
+
IFS='.' read -r MAJOR MINOR PATCH_FULL <<< "$CURRENT_VERSION"
|
|
83
|
+
|
|
84
|
+
# 分离 patch 和 prerelease(如 1.0.32-0 → patch=32, prerelease=0)
|
|
85
|
+
if [[ "$PATCH_FULL" == *-* ]]; then
|
|
86
|
+
PATCH="${PATCH_FULL%%-*}"
|
|
87
|
+
PRERELEASE="${PATCH_FULL#*-}"
|
|
88
|
+
else
|
|
89
|
+
PATCH="$PATCH_FULL"
|
|
90
|
+
PRERELEASE=""
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# ────────────────────────────────────────
|
|
94
|
+
# 计算各级别的目标版本
|
|
95
|
+
# ────────────────────────────────────────
|
|
96
|
+
|
|
97
|
+
NEXT_PATCH="$MAJOR.$MINOR.$((PATCH + 1))"
|
|
98
|
+
NEXT_MINOR="$MAJOR.$((MINOR + 1)).0"
|
|
99
|
+
NEXT_MAJOR="$((MAJOR + 1)).0.0"
|
|
100
|
+
|
|
101
|
+
if [ -n "$PRERELEASE" ]; then
|
|
102
|
+
NEXT_PRERELEASE="$MAJOR.$MINOR.$PATCH-$((PRERELEASE + 1))"
|
|
103
|
+
else
|
|
104
|
+
NEXT_PRERELEASE="$MAJOR.$MINOR.$PATCH-0"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# ────────────────────────────────────────
|
|
108
|
+
# 交互式选择版本级别
|
|
109
|
+
# ────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
echo -e "${BOLD}选择版本升级级别:${NC}"
|
|
112
|
+
echo ""
|
|
113
|
+
echo -e " ${CYAN}1)${NC} patch ${CURRENT_VERSION} → ${GREEN}${NEXT_PATCH}${NC} Bug 修复、小改动"
|
|
114
|
+
echo -e " ${CYAN}2)${NC} minor ${CURRENT_VERSION} → ${GREEN}${NEXT_MINOR}${NC} 新增功能、向后兼容"
|
|
115
|
+
echo -e " ${CYAN}3)${NC} major ${CURRENT_VERSION} → ${GREEN}${NEXT_MAJOR}${NC} 破坏性变更"
|
|
116
|
+
echo -e " ${CYAN}4)${NC} prerelease ${CURRENT_VERSION} → ${GREEN}${NEXT_PRERELEASE}${NC} 预发布/测试版本"
|
|
117
|
+
echo ""
|
|
118
|
+
read -rp "请选择 [1-4] (默认: 1): " CHOICE
|
|
119
|
+
CHOICE=${CHOICE:-1}
|
|
120
|
+
|
|
121
|
+
case "$CHOICE" in
|
|
122
|
+
1) NEW_VERSION="$NEXT_PATCH" ;;
|
|
123
|
+
2) NEW_VERSION="$NEXT_MINOR" ;;
|
|
124
|
+
3) NEW_VERSION="$NEXT_MAJOR" ;;
|
|
125
|
+
4) NEW_VERSION="$NEXT_PRERELEASE" ;;
|
|
126
|
+
*) print_error "无效的选择: $CHOICE" ;;
|
|
127
|
+
esac
|
|
128
|
+
|
|
129
|
+
echo ""
|
|
130
|
+
echo -e "${BOLD}即将发布: v${CURRENT_VERSION} → v${NEW_VERSION}${NC}"
|
|
131
|
+
read -rp "确认发布?(y/N) " CONFIRM
|
|
132
|
+
if [ "$CONFIRM" != "y" ] && [ "$CONFIRM" != "Y" ]; then
|
|
133
|
+
echo "已取消发布"
|
|
134
|
+
exit 0
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
echo ""
|
|
138
|
+
|
|
139
|
+
TAG="v${NEW_VERSION}"
|
|
140
|
+
|
|
141
|
+
# 回滚函数:npm publish 失败时撤销 commit、tag、push
|
|
142
|
+
# 参数 $1: 是否已推送到远程("pushed" 表示已推送)
|
|
143
|
+
rollback() {
|
|
144
|
+
local pushed="${1:-}"
|
|
145
|
+
echo ""
|
|
146
|
+
print_warning "正在回滚版本变更..."
|
|
147
|
+
|
|
148
|
+
# 回滚远程推送(仅在已推送时执行)
|
|
149
|
+
if [ "$pushed" = "pushed" ]; then
|
|
150
|
+
git push origin --delete "$TAG" 2>/dev/null && print_step "已删除远程 tag: ${TAG}" || print_warning "删除远程 tag 失败,请手动执行: git push origin --delete ${TAG}"
|
|
151
|
+
git push origin HEAD~1:refs/heads/"$(git branch --show-current)" --force-with-lease 2>/dev/null && print_step "已回退远程 commit" || print_warning "回退远程 commit 失败,请手动处理"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# 回滚本地 tag
|
|
155
|
+
git tag -d "$TAG" 2>/dev/null && print_step "已删除本地 tag: ${TAG}" || true
|
|
156
|
+
|
|
157
|
+
# 回滚本地 commit(回退到上一个 commit,保留文件改动后再还原)
|
|
158
|
+
git reset --hard HEAD~1 2>/dev/null && print_step "已回退本地 commit" || print_warning "回退本地 commit 失败,请手动处理"
|
|
159
|
+
|
|
160
|
+
echo ""
|
|
161
|
+
print_error "发布失败,所有变更已回滚"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# ────────────────────────────────────────
|
|
165
|
+
# 步骤 1: 构建
|
|
166
|
+
# ────────────────────────────────────────
|
|
167
|
+
|
|
168
|
+
print_step "构建项目..."
|
|
169
|
+
npm run build
|
|
170
|
+
print_success "构建完成"
|
|
171
|
+
|
|
172
|
+
# ────────────────────────────────────────
|
|
173
|
+
# 步骤 2: 更新 package.json 版本号
|
|
174
|
+
# ────────────────────────────────────────
|
|
175
|
+
|
|
176
|
+
print_step "更新版本号: ${CURRENT_VERSION} → ${NEW_VERSION}"
|
|
177
|
+
# 使用 npm version 更新版本号,--no-git-tag-version 避免 npm 自动打 tag
|
|
178
|
+
npm version "$NEW_VERSION" --no-git-tag-version > /dev/null
|
|
179
|
+
print_success "版本号已更新"
|
|
180
|
+
|
|
181
|
+
# ────────────────────────────────────────
|
|
182
|
+
# 步骤 3: 提交版本变更
|
|
183
|
+
# ────────────────────────────────────────
|
|
184
|
+
|
|
185
|
+
print_step "提交版本变更..."
|
|
186
|
+
git add package.json package-lock.json 2>/dev/null || git add package.json
|
|
187
|
+
git commit -m "build: bump version to ${NEW_VERSION}"
|
|
188
|
+
print_success "版本变更已提交"
|
|
189
|
+
|
|
190
|
+
# ────────────────────────────────────────
|
|
191
|
+
# 步骤 4: 创建 git tag
|
|
192
|
+
# ────────────────────────────────────────
|
|
193
|
+
|
|
194
|
+
print_step "创建 tag: ${TAG}"
|
|
195
|
+
git tag "$TAG"
|
|
196
|
+
print_success "tag 已创建: ${TAG}"
|
|
197
|
+
|
|
198
|
+
# ────────────────────────────────────────
|
|
199
|
+
# 步骤 5: 发布到 npm(先发布,成功后再推送 git)
|
|
200
|
+
# 调整顺序:npm publish 放在 git push 之前
|
|
201
|
+
# 如果 publish 失败,只需回滚本地 commit 和 tag,无需处理远程
|
|
202
|
+
# ────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
print_step "发布到 npm..."
|
|
205
|
+
# 临时关闭 set -e,手动捕获 npm publish 的退出码
|
|
206
|
+
set +e
|
|
207
|
+
NPM_OUTPUT=$(npm publish --access public --registry https://registry.npmjs.org/ 2>&1)
|
|
208
|
+
NPM_EXIT_CODE=$?
|
|
209
|
+
set -e
|
|
210
|
+
|
|
211
|
+
if [ $NPM_EXIT_CODE -ne 0 ]; then
|
|
212
|
+
echo ""
|
|
213
|
+
print_warning "npm publish 输出:"
|
|
214
|
+
echo "$NPM_OUTPUT"
|
|
215
|
+
echo ""
|
|
216
|
+
rollback "not_pushed"
|
|
217
|
+
fi
|
|
218
|
+
print_success "已发布到 npm"
|
|
219
|
+
|
|
220
|
+
# ────────────────────────────────────────
|
|
221
|
+
# 步骤 6: 推送 commit 和 tag 到远程仓库
|
|
222
|
+
# npm 发布成功后才推送,确保 git 和 npm 状态一致
|
|
223
|
+
# ────────────────────────────────────────
|
|
224
|
+
|
|
225
|
+
print_step "推送 commit 和 tag 到远程仓库..."
|
|
226
|
+
set +e
|
|
227
|
+
git push 2>&1
|
|
228
|
+
PUSH_EXIT_CODE=$?
|
|
229
|
+
set -e
|
|
230
|
+
|
|
231
|
+
if [ $PUSH_EXIT_CODE -ne 0 ]; then
|
|
232
|
+
print_warning "git push 失败,但 npm 已发布 v${NEW_VERSION}"
|
|
233
|
+
print_warning "请手动执行: git push && git push origin ${TAG}"
|
|
234
|
+
exit 1
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
set +e
|
|
238
|
+
git push origin "$TAG" 2>&1
|
|
239
|
+
TAG_PUSH_EXIT_CODE=$?
|
|
240
|
+
set -e
|
|
241
|
+
|
|
242
|
+
if [ $TAG_PUSH_EXIT_CODE -ne 0 ]; then
|
|
243
|
+
print_warning "tag 推送失败,但 npm 已发布 v${NEW_VERSION},commit 已推送"
|
|
244
|
+
print_warning "请手动执行: git push origin ${TAG}"
|
|
245
|
+
exit 1
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
print_success "已推送到远程仓库"
|
|
249
|
+
|
|
250
|
+
# ────────────────────────────────────────
|
|
251
|
+
# 完成
|
|
252
|
+
# ────────────────────────────────────────
|
|
253
|
+
|
|
254
|
+
echo ""
|
|
255
|
+
echo -e "${GREEN}${BOLD}════════════════════════════════════════${NC}"
|
|
256
|
+
echo -e "${GREEN}${BOLD} 发布完成! v${NEW_VERSION}${NC}"
|
|
257
|
+
echo -e "${GREEN}${BOLD}════════════════════════════════════════${NC}"
|
|
258
|
+
echo ""
|
|
259
|
+
echo -e " npm: https://www.npmjs.com/package/clawt"
|
|
260
|
+
echo -e " tag: ${TAG}"
|
|
261
|
+
echo ""
|