@zjex/git-workflow 0.2.24 → 0.3.0
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/.github/workflows/deploy-docs.yml +68 -0
- package/.github/workflows/test.yml +24 -4
- package/.husky/pre-commit +14 -0
- package/README.md +72 -1066
- package/dist/index.js +103 -13
- package/docs/.vitepress/cache/deps/_metadata.json +52 -0
- package/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js +9719 -0
- package/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js.map +7 -0
- package/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js +12824 -0
- package/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js.map +7 -0
- package/docs/.vitepress/cache/deps/package.json +3 -0
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4505 -0
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +583 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1352 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1665 -0
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js +1813 -0
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
- package/docs/.vitepress/cache/deps/vue.js +347 -0
- package/docs/.vitepress/cache/deps/vue.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-2CLQ7TTZ.js +9719 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-2CLQ7TTZ.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-LE5NDSFD.js +12824 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-LE5NDSFD.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/package.json +3 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vue_devtools-api.js +4505 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vue_devtools-api.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_core.js +583 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_core.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_integrations_useFocusTrap.js +1352 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___mark__js_src_vanilla__js.js +1665 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___minisearch.js +1813 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___minisearch.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vue.js +347 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vue.js.map +7 -0
- package/docs/.vitepress/config.ts +167 -0
- package/docs/.vitepress/theme/custom.css +39 -0
- package/docs/.vitepress/theme/index.ts +4 -0
- package/docs/README.md +82 -0
- package/docs/commands/branch.md +468 -0
- package/docs/commands/commit.md +554 -0
- package/docs/commands/config.md +346 -0
- package/docs/commands/index.md +312 -0
- package/docs/commands/interactive.md +384 -0
- package/docs/commands/release.md +300 -0
- package/docs/commands/stash.md +309 -0
- package/docs/commands/tag.md +278 -0
- package/docs/commands/update.md +347 -0
- package/docs/config/ai-config.md +160 -0
- package/docs/config/branch-config.md +133 -0
- package/docs/config/commit-config.md +185 -0
- package/docs/config/config-file.md +776 -0
- package/docs/config/examples.md +279 -0
- package/docs/config/index.md +478 -0
- package/docs/guide/ai-commit.md +576 -0
- package/docs/guide/basic-usage.md +522 -0
- package/docs/guide/best-practices.md +426 -0
- package/docs/guide/branch-management.md +712 -0
- package/docs/guide/getting-started.md +294 -0
- package/docs/guide/index.md +168 -0
- package/docs/guide/installation.md +449 -0
- package/docs/guide/release-management.md +744 -0
- package/docs/guide/stash-management.md +608 -0
- package/docs/guide/tag-management.md +614 -0
- package/docs/index.md +205 -0
- package/docs/public/favicon.svg +21 -0
- package/docs/public/hero-logo.svg +43 -0
- package/docs/public/logo.svg +20 -0
- package/package.json +11 -2
- package/scripts/publish.js +55 -8
- package/scripts/publish.sh +20 -2
- package/scripts/release.sh +20 -2
- package/scripts/update-test-count.js +55 -0
- package/src/ai-service.ts +101 -15
- package/src/commands/init.ts +18 -0
- package/src/config.ts +1 -0
- package/tests/ai-service.test.ts +237 -2
- package/tests/help.test.ts +134 -0
- package/tests/init.test.ts +582 -0
- package/tests/release.test.ts +333 -0
- package/tests/setup.ts +21 -0
- package/tests/stash.test.ts +376 -0
- package/tests/update.test.ts +402 -0
- package/vitest.config.ts +3 -0
- package/zjex-logo.svg +22 -0
- package/zjex-optimized.svg +34 -0
- package/zjex.svg +1 -0
package/docs/index.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: home
|
|
3
|
+
|
|
4
|
+
hero:
|
|
5
|
+
name: "Git Workflow"
|
|
6
|
+
text: "极简的 Git 工作流 CLI 工具"
|
|
7
|
+
tagline: "让分支管理和版本发布变得轻松愉快"
|
|
8
|
+
image:
|
|
9
|
+
src: /hero-logo.svg
|
|
10
|
+
alt: Git Workflow Logo
|
|
11
|
+
actions:
|
|
12
|
+
- theme: brand
|
|
13
|
+
text: 快速开始
|
|
14
|
+
link: /guide/getting-started
|
|
15
|
+
- theme: alt
|
|
16
|
+
text: 查看 GitHub
|
|
17
|
+
link: https://github.com/iamzjt-front-end/git-workflow
|
|
18
|
+
|
|
19
|
+
features:
|
|
20
|
+
- icon: 🤖
|
|
21
|
+
title: AI 智能提交
|
|
22
|
+
details: 使用 AI 自动分析代码变更生成 commit message,支持 GitHub Models、OpenAI 等多种提供商
|
|
23
|
+
- icon: 🎯
|
|
24
|
+
title: 规范命名
|
|
25
|
+
details: 自动生成带日期的规范分支名,如 feature/20260109-PROJ-123-add-login
|
|
26
|
+
- icon: 🏷️
|
|
27
|
+
title: 智能版本
|
|
28
|
+
details: 自动识别当前版本,交互式选择下一版本,支持 semver + 预发布版本
|
|
29
|
+
- icon: 📝
|
|
30
|
+
title: 规范提交
|
|
31
|
+
details: 遵循 Conventional Commits + Gitmoji,提交信息更清晰规范
|
|
32
|
+
- icon: 🗑️
|
|
33
|
+
title: 批量清理
|
|
34
|
+
details: 一键删除本地+远程分支,按最近使用排序,智能检测远程分支状态
|
|
35
|
+
- icon: 💾
|
|
36
|
+
title: Stash 管理
|
|
37
|
+
details: 可视化管理 stash,支持预览、应用、创建分支等操作
|
|
38
|
+
- icon: ⚙️
|
|
39
|
+
title: 灵活配置
|
|
40
|
+
details: 支持项目级和全局配置,不同项目可使用不同规范
|
|
41
|
+
- icon: 🔔
|
|
42
|
+
title: 版本提醒
|
|
43
|
+
details: 自动检测新版本,一键更新,保持工具始终最新
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 🎯 为什么选择 Git Workflow?
|
|
47
|
+
|
|
48
|
+
在日常开发中,你是否经常遇到这些问题:
|
|
49
|
+
|
|
50
|
+
- 🤔 每次创建分支都要手动输入一长串命名规范?
|
|
51
|
+
- 😫 发布版本时总是忘记当前版本号是多少?
|
|
52
|
+
- 📝 提交信息格式不统一,难以生成 CHANGELOG?
|
|
53
|
+
- 🔄 删除分支时需要分别处理本地和远程?
|
|
54
|
+
- 📋 团队成员的分支命名风格五花八门?
|
|
55
|
+
- 💬 写 commit message 总是词穷,不知道怎么描述?
|
|
56
|
+
|
|
57
|
+
**Git Workflow** 就是为解决这些痛点而生的。它提供了一套简洁的命令,让你专注于编码,而不是 Git 操作。
|
|
58
|
+
|
|
59
|
+
## ⚡️ 快速开始
|
|
60
|
+
|
|
61
|
+
### 安装
|
|
62
|
+
|
|
63
|
+
::: code-group
|
|
64
|
+
|
|
65
|
+
```bash [npm]
|
|
66
|
+
npm install -g @zjex/git-workflow
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```bash [pnpm]
|
|
70
|
+
pnpm add -g @zjex/git-workflow
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```bash [yarn]
|
|
74
|
+
yarn global add @zjex/git-workflow
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
:::
|
|
78
|
+
|
|
79
|
+
### 三步开始使用
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# 第 1 步:创建全局配置(只需一次)
|
|
83
|
+
gw init
|
|
84
|
+
# 选择 "全局配置(所有项目生效)"
|
|
85
|
+
# 配置 AI commit、分支规范等
|
|
86
|
+
|
|
87
|
+
# 第 2 步:在任意项目中使用
|
|
88
|
+
cd your-project
|
|
89
|
+
gw c # AI 自动生成 commit message
|
|
90
|
+
gw f # 创建规范的 feature 分支
|
|
91
|
+
gw t # 创建语义化版本 tag
|
|
92
|
+
|
|
93
|
+
# 第 3 步:享受高效的 Git 工作流 🎉
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 🌟 核心特性
|
|
97
|
+
|
|
98
|
+
### 🤖 AI 智能提交
|
|
99
|
+
|
|
100
|
+
使用 AI 自动分析代码变更生成 commit message,2-3 秒完成,支持多种 AI 提供商:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
gw c
|
|
104
|
+
# 已暂存的文件:
|
|
105
|
+
# src/auth.ts
|
|
106
|
+
# src/login.ts
|
|
107
|
+
# ────────────────────────────────────────
|
|
108
|
+
# ? 选择 commit 方式:
|
|
109
|
+
# ❯ 🤖 AI 自动生成 commit message
|
|
110
|
+
# ✍️ 手动编写 commit message
|
|
111
|
+
#
|
|
112
|
+
# ✔ AI 生成完成
|
|
113
|
+
#
|
|
114
|
+
# AI 生成的 commit message:
|
|
115
|
+
# ✨ feat(auth): 添加用户登录功能
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 🎯 规范分支命名
|
|
119
|
+
|
|
120
|
+
自动生成带日期的规范分支名,支持自定义前缀和 ID 标签:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
gw f
|
|
124
|
+
# ? 请输入 Story ID (可跳过): PROJ-123
|
|
125
|
+
# ? 请输入描述: add-user-login
|
|
126
|
+
# ✔ 分支创建成功: feature/20260109-PROJ-123-add-user-login
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 🏷️ 智能版本管理
|
|
130
|
+
|
|
131
|
+
自动检测现有 tag 前缀,智能递增版本号:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
gw t
|
|
135
|
+
# ? 选择 tag 前缀: v (最新: v1.2.0)
|
|
136
|
+
# ? 选择版本类型:
|
|
137
|
+
# ❯ patch → v1.2.1
|
|
138
|
+
# minor → v1.3.0
|
|
139
|
+
# major → v2.0.0
|
|
140
|
+
# alpha → v1.2.1-alpha.1
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 💾 可视化 Stash 管理
|
|
144
|
+
|
|
145
|
+
原生 `git stash list` 输出难以阅读,Git Workflow 提供清晰的交互式界面:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
gw s
|
|
149
|
+
# 共 3 个 stash:
|
|
150
|
+
#
|
|
151
|
+
# ? 选择 stash:
|
|
152
|
+
# [0] main fix login bug (3 文件) 2 hours ago
|
|
153
|
+
# [1] develop add new feature (5 文件) 1 day ago
|
|
154
|
+
# [2] main WIP (1 文件) 3 days ago
|
|
155
|
+
# + 创建新 stash
|
|
156
|
+
# 取消
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 📊 与其他工具对比
|
|
160
|
+
|
|
161
|
+
| 特性 | Git Workflow | git-flow | 手动操作 |
|
|
162
|
+
| ---------------- | ------------- | ----------- | --------- |
|
|
163
|
+
| 学习成本 | ⭐ 极低 | ⭐⭐⭐ 较高 | ⭐⭐ 中等 |
|
|
164
|
+
| 分支命名规范 | ✅ 自动生成 | ❌ 需手动 | ❌ 需手动 |
|
|
165
|
+
| 版本号管理 | ✅ 智能递增 | ❌ 需手动 | ❌ 需手动 |
|
|
166
|
+
| AI Commit | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
|
|
167
|
+
| Stash 可视化管理 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
|
|
168
|
+
| 交互式操作 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
|
|
169
|
+
| 配置灵活性 | ✅ 项目级配置 | ⚠️ 有限 | - |
|
|
170
|
+
|
|
171
|
+
## 🎨 优雅的用户界面
|
|
172
|
+
|
|
173
|
+
Git Workflow 提供优雅的命令行界面,支持键盘快捷操作:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
███████╗ ██╗███████╗██╗ ██╗
|
|
177
|
+
╚══███╔╝ ██║██╔════╝╚██╗██╔╝
|
|
178
|
+
███╔╝ ██║█████╗ ╚███╔╝
|
|
179
|
+
███╔╝ ██ ██║██╔══╝ ██╔██╗
|
|
180
|
+
███████╗╚█████╔╝███████╗██╔╝ ██╗
|
|
181
|
+
╚══════╝ ╚════╝ ╚══════╝╚═╝ ╚═╝
|
|
182
|
+
|
|
183
|
+
git-workflow v0.2.24
|
|
184
|
+
|
|
185
|
+
? 选择操作:
|
|
186
|
+
[1] ✨ 创建 feature 分支 gw f
|
|
187
|
+
[2] 🐛 创建 hotfix 分支 gw h
|
|
188
|
+
[3] 🗑️ 删除分支 gw d
|
|
189
|
+
[4] 📝 提交代码 gw c
|
|
190
|
+
[5] 🏷️ 创建 tag gw t
|
|
191
|
+
...
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 🤝 社区与支持
|
|
195
|
+
|
|
196
|
+
- 📖 [完整文档](/guide/)
|
|
197
|
+
- 🐛 [问题反馈](https://github.com/iamzjt-front-end/git-workflow/issues)
|
|
198
|
+
- 💡 [功能建议](https://github.com/iamzjt-front-end/git-workflow/discussions)
|
|
199
|
+
- 📦 [npm 包](https://www.npmjs.com/package/@zjex/git-workflow)
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
<div style="text-align: center; margin-top: 2rem;">
|
|
204
|
+
<strong>如果这个工具对你有帮助,请给个 ⭐️ 支持一下!</strong>
|
|
205
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
2
|
+
<rect width="64" height="64" rx="8" fill="#ffffff"/>
|
|
3
|
+
<!-- 基于 zjex.svg 的交叉图案,放大版本用作 favicon -->
|
|
4
|
+
<g transform="translate(6, 6) scale(0.52)">
|
|
5
|
+
<!-- 蓝色条纹 -->
|
|
6
|
+
<path d="M69.3 59.41l-9.89 9.89L51 77.73 30.46 98.26A6 6 0 0 1 22 89.83L42.56 69.3 51 60.88l9.9-9.9z" fill="#0059cc"/>
|
|
7
|
+
<path d="M102 24.28a6 6 0 0 1-1.75 4.21L77.72 51l-8.42-8.44 22.5-22.5a6 6 0 0 1 10.2 4.22z" fill="#0059cc"/>
|
|
8
|
+
|
|
9
|
+
<!-- 青色条纹 -->
|
|
10
|
+
<path d="M83.64 6a5.94 5.94 0 0 1-1.74 4.21L41.08 51l-8.42-8.42 9.9-9.89L51 24.24 73.48 1.75A6 6 0 0 1 83.64 6z" fill="#00dac7"/>
|
|
11
|
+
<path d="M32.66 59.41L12.13 79.93a6 6 0 0 1-8.42-8.42L24.24 51z" fill="#00dac7"/>
|
|
12
|
+
|
|
13
|
+
<!-- 浅蓝色条纹 -->
|
|
14
|
+
<path d="M51 24.24l-8.42 8.43-22.5-22.5A6 6 0 0 1 24.28 0a5.89 5.89 0 0 1 4.2 1.75z" fill="#00baec"/>
|
|
15
|
+
<path d="M98.25 79.93a5.94 5.94 0 0 1-8.42 0L51 41.09l8.42-8.42 9.9 9.89 8.4 8.44 20.53 20.51a6 6 0 0 1 0 8.42z" fill="#00baec"/>
|
|
16
|
+
|
|
17
|
+
<!-- 深蓝色条纹 -->
|
|
18
|
+
<path d="M51 60.88l-8.44 8.42L1.74 28.49a6 6 0 0 1 8.43-8.43l22.49 22.5L41.08 51z" fill="#00abd8"/>
|
|
19
|
+
<path d="M79.93 98.26a6 6 0 0 1-8.42 0L51 77.73l8.42-8.43 20.51 20.53a6 6 0 0 1 0 8.43z" fill="#00abd8"/>
|
|
20
|
+
</g>
|
|
21
|
+
</svg>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1800 1800" width="320" height="320">
|
|
2
|
+
<!-- 简洁版本 - 无背景渐变 -->
|
|
3
|
+
|
|
4
|
+
<defs>
|
|
5
|
+
<!-- 原有的logo渐变 -->
|
|
6
|
+
<linearGradient id="blueGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
7
|
+
<stop offset="0%" style="stop-color:#00baec;stop-opacity:1" />
|
|
8
|
+
<stop offset="100%" style="stop-color:#0059cc;stop-opacity:1" />
|
|
9
|
+
</linearGradient>
|
|
10
|
+
<linearGradient id="cyanGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
11
|
+
<stop offset="0%" style="stop-color:#00dac7;stop-opacity:1" />
|
|
12
|
+
<stop offset="100%" style="stop-color:#00baec;stop-opacity:1" />
|
|
13
|
+
</linearGradient>
|
|
14
|
+
|
|
15
|
+
<!-- 发光效果 -->
|
|
16
|
+
<filter id="glow">
|
|
17
|
+
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
|
|
18
|
+
<feMerge>
|
|
19
|
+
<feMergeNode in="coloredBlur"/>
|
|
20
|
+
<feMergeNode in="SourceGraphic"/>
|
|
21
|
+
</feMerge>
|
|
22
|
+
</filter>
|
|
23
|
+
</defs>
|
|
24
|
+
|
|
25
|
+
<!-- 交叉图案 - 保持原有颜色和效果 -->
|
|
26
|
+
<g transform="translate(900, 900) scale(16.2) translate(-51, -50)" filter="url(#glow)">
|
|
27
|
+
<!-- 蓝色条纹 - 使用渐变 -->
|
|
28
|
+
<path d="M69.3 59.41l-9.89 9.89L51 77.73 30.46 98.26A6 6 0 0 1 22 89.83L42.56 69.3 51 60.88l9.9-9.9z" fill="url(#blueGrad)"/>
|
|
29
|
+
<path d="M102 24.28a6 6 0 0 1-1.75 4.21L77.72 51l-8.42-8.44 22.5-22.5a6 6 0 0 1 10.2 4.22z" fill="url(#blueGrad)"/>
|
|
30
|
+
|
|
31
|
+
<!-- 青色条纹 - 使用渐变 -->
|
|
32
|
+
<path d="M83.64 6a5.94 5.94 0 0 1-1.74 4.21L41.08 51l-8.42-8.42 9.9-9.89L51 24.24 73.48 1.75A6 6 0 0 1 83.64 6z" fill="url(#cyanGrad)"/>
|
|
33
|
+
<path d="M32.66 59.41L12.13 79.93a6 6 0 0 1-8.42-8.42L24.24 51z" fill="url(#cyanGrad)"/>
|
|
34
|
+
|
|
35
|
+
<!-- 浅蓝色条纹 -->
|
|
36
|
+
<path d="M51 24.24l-8.42 8.43-22.5-22.5A6 6 0 0 1 24.28 0a5.89 5.89 0 0 1 4.2 1.75z" fill="#00baec"/>
|
|
37
|
+
<path d="M98.25 79.93a5.94 5.94 0 0 1-8.42 0L51 41.09l8.42-8.42 9.9 9.89 8.4 8.44 20.53 20.51a6 6 0 0 1 0 8.42z" fill="#00baec"/>
|
|
38
|
+
|
|
39
|
+
<!-- 深蓝色条纹 -->
|
|
40
|
+
<path d="M51 60.88l-8.44 8.42L1.74 28.49a6 6 0 0 1 8.43-8.43l22.49 22.5L41.08 51z" fill="#00abd8"/>
|
|
41
|
+
<path d="M79.93 98.26a6 6 0 0 1-8.42 0L51 77.73l8.42-8.43 20.51 20.53a6 6 0 0 1 0 8.43z" fill="#00abd8"/>
|
|
42
|
+
</g>
|
|
43
|
+
</svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 100" width="96" height="96">
|
|
2
|
+
<!-- 简洁版本 - 用于导航栏 -->
|
|
3
|
+
<g transform="translate(60, 50) scale(0.9) translate(-51, -50)">
|
|
4
|
+
<!-- 蓝色条纹 -->
|
|
5
|
+
<path d="M69.3 59.41l-9.89 9.89L51 77.73 30.46 98.26A6 6 0 0 1 22 89.83L42.56 69.3 51 60.88l9.9-9.9z" fill="#0059cc"/>
|
|
6
|
+
<path d="M102 24.28a6 6 0 0 1-1.75 4.21L77.72 51l-8.42-8.44 22.5-22.5a6 6 0 0 1 10.2 4.22z" fill="#0059cc"/>
|
|
7
|
+
|
|
8
|
+
<!-- 青色条纹 -->
|
|
9
|
+
<path d="M83.64 6a5.94 5.94 0 0 1-1.74 4.21L41.08 51l-8.42-8.42 9.9-9.89L51 24.24 73.48 1.75A6 6 0 0 1 83.64 6z" fill="#00dac7"/>
|
|
10
|
+
<path d="M32.66 59.41L12.13 79.93a6 6 0 0 1-8.42-8.42L24.24 51z" fill="#00dac7"/>
|
|
11
|
+
|
|
12
|
+
<!-- 浅蓝色条纹 -->
|
|
13
|
+
<path d="M51 24.24l-8.42 8.43-22.5-22.5A6 6 0 0 1 24.28 0a5.89 5.89 0 0 1 4.2 1.75z" fill="#00baec"/>
|
|
14
|
+
<path d="M98.25 79.93a5.94 5.94 0 0 1-8.42 0L51 41.09l8.42-8.42 9.9 9.89 8.4 8.44 20.53 20.51a6 6 0 0 1 0 8.42z" fill="#00baec"/>
|
|
15
|
+
|
|
16
|
+
<!-- 深蓝色条纹 -->
|
|
17
|
+
<path d="M51 60.88l-8.44 8.42L1.74 28.49a6 6 0 0 1 8.43-8.43l22.49 22.5L41.08 51z" fill="#00abd8"/>
|
|
18
|
+
<path d="M79.93 98.26a6 6 0 0 1-8.42 0L51 77.73l8.42-8.43 20.51 20.53a6 6 0 0 1 0 8.43z" fill="#00abd8"/>
|
|
19
|
+
</g>
|
|
20
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zjex/git-workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "🚀 极简的 Git 工作流 CLI 工具,让分支管理和版本发布变得轻松愉快",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,13 +17,17 @@
|
|
|
17
17
|
"test:watch": "vitest",
|
|
18
18
|
"test:ui": "vitest --ui",
|
|
19
19
|
"test:coverage": "vitest --coverage",
|
|
20
|
+
"test:update-readme": "node scripts/update-test-count.js",
|
|
20
21
|
"changelog": "changelogen -o CHANGELOG.md",
|
|
21
22
|
"version": "node scripts/version.js",
|
|
22
23
|
"release": "./scripts/release.sh",
|
|
23
24
|
"release:dry": "./scripts/release.sh --dry-run",
|
|
24
25
|
"publish:npm": "NODE_NO_WARNINGS=1 node scripts/publish.js",
|
|
25
26
|
"prepublishOnly": "npm run build",
|
|
26
|
-
"prepare": "husky"
|
|
27
|
+
"prepare": "husky",
|
|
28
|
+
"docs:dev": "vitepress dev docs",
|
|
29
|
+
"docs:build": "vitepress build docs",
|
|
30
|
+
"docs:preview": "npm run docs:build && vitepress preview docs"
|
|
27
31
|
},
|
|
28
32
|
"keywords": [
|
|
29
33
|
"git",
|
|
@@ -34,6 +38,10 @@
|
|
|
34
38
|
],
|
|
35
39
|
"author": "zjex",
|
|
36
40
|
"license": "MIT",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.0.0",
|
|
43
|
+
"npm": ">=9.0.0"
|
|
44
|
+
},
|
|
37
45
|
"repository": {
|
|
38
46
|
"type": "git",
|
|
39
47
|
"url": "git+https://github.com/iamzjt-front-end/git-workflow.git"
|
|
@@ -59,6 +67,7 @@
|
|
|
59
67
|
"tsup": "^8.5.1",
|
|
60
68
|
"tsx": "^4.21.0",
|
|
61
69
|
"typescript": "^5.9.3",
|
|
70
|
+
"vitepress": "^1.6.4",
|
|
62
71
|
"vitest": "^4.0.16"
|
|
63
72
|
}
|
|
64
73
|
}
|
package/scripts/publish.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { execSync } from "child_process";
|
|
3
|
+
import { execSync, spawn } from "child_process";
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
5
|
import ora from "ora";
|
|
6
6
|
import boxen from "boxen";
|
|
@@ -96,14 +96,61 @@ async function main() {
|
|
|
96
96
|
const npmUser = exec("npm whoami", true);
|
|
97
97
|
if (!npmUser) {
|
|
98
98
|
spinner3.fail(`${colors.blue("[3/11]")} 检查 npm 登录状态`);
|
|
99
|
-
console.log(colors.
|
|
100
|
-
|
|
99
|
+
console.log(colors.yellow("⚠️ 未登录 npm,需要先登录"));
|
|
100
|
+
console.log(colors.dim("正在为你打开 npm 登录..."));
|
|
101
|
+
console.log("");
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// 使用 spawn 而不是 exec,以便用户可以交互
|
|
105
|
+
const loginProcess = spawn("npm", ["login"], {
|
|
106
|
+
stdio: "inherit", // 继承父进程的 stdio,允许用户交互
|
|
107
|
+
shell: true
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// 等待登录完成
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
loginProcess.on("close", (code) => {
|
|
113
|
+
if (code === 0) {
|
|
114
|
+
resolve();
|
|
115
|
+
} else {
|
|
116
|
+
reject(new Error(`npm login 失败,退出码: ${code}`));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
loginProcess.on("error", (error) => {
|
|
121
|
+
reject(error);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
console.log("");
|
|
126
|
+
console.log(colors.green("✅ npm 登录成功!"));
|
|
127
|
+
console.log(colors.dim("继续发布流程..."));
|
|
128
|
+
console.log("");
|
|
129
|
+
|
|
130
|
+
// 重新检查登录状态
|
|
131
|
+
const newNpmUser = exec("npm whoami", true);
|
|
132
|
+
if (!newNpmUser) {
|
|
133
|
+
console.log(colors.red("✖ 登录验证失败,请手动执行: npm login"));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
spinner3.succeed(
|
|
138
|
+
`${colors.blue("[3/11]")} 检查 npm 登录状态 ${colors.dim(
|
|
139
|
+
`(${newNpmUser.trim()})`
|
|
140
|
+
)}`
|
|
141
|
+
);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.log(colors.red("✖ npm 登录失败:"), error.message);
|
|
144
|
+
console.log(colors.dim("请手动执行: npm login"));
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
spinner3.succeed(
|
|
149
|
+
`${colors.blue("[3/11]")} 检查 npm 登录状态 ${colors.dim(
|
|
150
|
+
`(${npmUser.trim()})`
|
|
151
|
+
)}`
|
|
152
|
+
);
|
|
101
153
|
}
|
|
102
|
-
spinner3.succeed(
|
|
103
|
-
`${colors.blue("[3/11]")} 检查 npm 登录状态 ${colors.dim(
|
|
104
|
-
`(${npmUser.trim()})`
|
|
105
|
-
)}`
|
|
106
|
-
);
|
|
107
154
|
|
|
108
155
|
// 获取当前分支
|
|
109
156
|
const currentBranch = exec("git branch --show-current", true).trim();
|
package/scripts/publish.sh
CHANGED
|
@@ -123,8 +123,26 @@ fi
|
|
|
123
123
|
echo -ne "${BLUE}[3/${TOTAL_STEPS}]${NC} 检查 npm 登录状态... "
|
|
124
124
|
if ! npm whoami &> /dev/null; then
|
|
125
125
|
echo -e "${RED}❌${NC}"
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
echo -e "${YELLOW}⚠️ 未登录 npm,需要先登录${NC}"
|
|
127
|
+
echo -e "${DIM}正在为你打开 npm 登录...${NC}"
|
|
128
|
+
echo ""
|
|
129
|
+
|
|
130
|
+
# 执行 npm login
|
|
131
|
+
if npm login; then
|
|
132
|
+
echo ""
|
|
133
|
+
echo -e "${GREEN}✅ npm 登录成功!${NC}"
|
|
134
|
+
echo -e "${DIM}继续发布流程...${NC}"
|
|
135
|
+
echo ""
|
|
136
|
+
|
|
137
|
+
# 重新检查登录状态
|
|
138
|
+
if ! npm whoami &> /dev/null; then
|
|
139
|
+
print_error "登录验证失败,请手动执行: npm login"
|
|
140
|
+
exit 1
|
|
141
|
+
fi
|
|
142
|
+
else
|
|
143
|
+
print_error "npm 登录失败,请手动执行: npm login"
|
|
144
|
+
exit 1
|
|
145
|
+
fi
|
|
128
146
|
fi
|
|
129
147
|
NPM_USER=$(npm whoami)
|
|
130
148
|
echo -e "${GREEN}✅${NC} ${DIM}(${NPM_USER})${NC}"
|
package/scripts/release.sh
CHANGED
|
@@ -111,8 +111,26 @@ fi
|
|
|
111
111
|
# 检查 npm 登录状态
|
|
112
112
|
print_step "检查 npm 登录状态..."
|
|
113
113
|
if ! npm whoami &> /dev/null; then
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
echo -e "${YELLOW}⚠️ 未登录 npm,需要先登录${NC}"
|
|
115
|
+
echo -e "${DIM}正在为你打开 npm 登录...${NC}"
|
|
116
|
+
echo ""
|
|
117
|
+
|
|
118
|
+
# 执行 npm login
|
|
119
|
+
if npm login; then
|
|
120
|
+
echo ""
|
|
121
|
+
echo -e "${GREEN}✅ npm 登录成功!${NC}"
|
|
122
|
+
echo -e "${DIM}继续发布流程...${NC}"
|
|
123
|
+
echo ""
|
|
124
|
+
|
|
125
|
+
# 重新检查登录状态
|
|
126
|
+
if ! npm whoami &> /dev/null; then
|
|
127
|
+
print_error "登录验证失败,请手动执行: npm login"
|
|
128
|
+
exit 1
|
|
129
|
+
fi
|
|
130
|
+
else
|
|
131
|
+
print_error "npm 登录失败,请手动执行: npm login"
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
116
134
|
fi
|
|
117
135
|
NPM_USER=$(npm whoami)
|
|
118
136
|
print_success "已登录 npm (用户: ${NPM_USER})"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
// 运行测试并获取结果
|
|
8
|
+
console.log('🧪 运行测试...');
|
|
9
|
+
const testOutput = execSync('npm test', { encoding: 'utf8' });
|
|
10
|
+
|
|
11
|
+
// 从测试输出中提取测试数量
|
|
12
|
+
// 移除ANSI颜色代码,然后匹配测试总数
|
|
13
|
+
const cleanOutput = testOutput.replace(/\x1B\[[0-9;]*m/g, '');
|
|
14
|
+
const testMatch = cleanOutput.match(/Tests\s+(\d+)\s+passed\s+\(\d+\)/);
|
|
15
|
+
|
|
16
|
+
let testCount = 0;
|
|
17
|
+
if (testMatch) {
|
|
18
|
+
testCount = parseInt(testMatch[1]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (testCount === 0) {
|
|
22
|
+
console.log('❌ 无法从测试输出中提取测试数量');
|
|
23
|
+
console.log('测试输出:', testOutput.slice(-500)); // 显示最后500字符用于调试
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.log(`✅ 检测到 ${testCount} 个测试用例`);
|
|
28
|
+
|
|
29
|
+
// 读取README文件
|
|
30
|
+
const readmePath = 'README.md';
|
|
31
|
+
let readmeContent = readFileSync(readmePath, 'utf8');
|
|
32
|
+
|
|
33
|
+
// 更新测试徽章
|
|
34
|
+
const badgeRegex = /tests-\d+%20passed/g;
|
|
35
|
+
const newBadge = `tests-${testCount}%20passed`;
|
|
36
|
+
|
|
37
|
+
if (readmeContent.match(badgeRegex)) {
|
|
38
|
+
const oldContent = readmeContent;
|
|
39
|
+
readmeContent = readmeContent.replace(badgeRegex, newBadge);
|
|
40
|
+
|
|
41
|
+
if (oldContent !== readmeContent) {
|
|
42
|
+
writeFileSync(readmePath, readmeContent);
|
|
43
|
+
console.log(`✅ README中的测试数量已更新为 ${testCount}`);
|
|
44
|
+
} else {
|
|
45
|
+
console.log(`ℹ️ 测试数量无变化,保持 ${testCount}`);
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
console.log('❌ 未找到测试徽章,无法更新');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('❌ 更新测试数量失败:', error.message);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|