zengen 0.1.1 → 0.1.31
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/README-CI.md +120 -0
- package/.github/workflows/README-PAGES.md +104 -0
- package/.github/workflows/ci.yml +69 -0
- package/.github/workflows/pages.yml +119 -0
- package/.github/workflows/publish.yml +81 -0
- package/.github/workflows/version.yml +88 -0
- package/dist/builder.d.ts +4 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +42 -2
- package/dist/builder.js.map +1 -1
- package/dist/cli.js +33 -1
- package/dist/cli.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/builder.ts +46 -2
- package/src/cli.ts +39 -1
- package/src/types.ts +3 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# GitHub CI/CD 配置指南
|
|
2
|
+
|
|
3
|
+
本文档描述了如何为 zengen 项目配置 GitHub Actions 进行可信发布。
|
|
4
|
+
|
|
5
|
+
## 概述
|
|
6
|
+
|
|
7
|
+
我们配置了三个 GitHub Actions workflows:
|
|
8
|
+
|
|
9
|
+
1. **CI** (`ci.yml`) - 代码质量检查和测试
|
|
10
|
+
2. **Version Management** (`version.yml`) - 版本管理和自动创建 Release
|
|
11
|
+
3. **Publish to npm** (`publish.yml`) - 可信发布到 npm registry
|
|
12
|
+
|
|
13
|
+
## 配置步骤
|
|
14
|
+
|
|
15
|
+
### 1. 设置 npm 认证令牌
|
|
16
|
+
|
|
17
|
+
由于 npm 经典令牌已被撤销,需要使用新的认证方式:
|
|
18
|
+
|
|
19
|
+
#### 选项 A: 使用细粒度访问令牌(推荐)
|
|
20
|
+
1. 登录 [npmjs.com](https://www.npmjs.com)
|
|
21
|
+
2. 进入 Account Settings → Access Tokens
|
|
22
|
+
3. 点击 "Create New Token"
|
|
23
|
+
4. 选择 "Automation" 类型
|
|
24
|
+
5. 配置权限:
|
|
25
|
+
- 读取和写入包
|
|
26
|
+
- 绕过 2FA(用于自动化工作流)
|
|
27
|
+
6. 设置有效期(最长 90 天)
|
|
28
|
+
7. 复制生成的令牌
|
|
29
|
+
|
|
30
|
+
#### 选项 B: 使用 OIDC 可信发布
|
|
31
|
+
1. 确保在 GitHub 仓库设置中启用了 OIDC
|
|
32
|
+
2. 配置 npm 以信任 GitHub Actions 的 OIDC 令牌
|
|
33
|
+
|
|
34
|
+
### 2. 配置 GitHub Actions 权限
|
|
35
|
+
|
|
36
|
+
确保仓库有以下权限设置:
|
|
37
|
+
- Settings → Actions → General
|
|
38
|
+
- Workflow permissions: 选择 "Read and write permissions"
|
|
39
|
+
- 确保启用了 OIDC 支持
|
|
40
|
+
|
|
41
|
+
**注意**:对于 npm OIDC 发布,不需要配置 `NPM_TOKEN` secret。GitHub Actions 会自动使用 OIDC 令牌进行认证。
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## 工作流程
|
|
45
|
+
|
|
46
|
+
### CI 流程
|
|
47
|
+
1. 当有 push 到 main 分支或创建 PR 时触发
|
|
48
|
+
2. 在多个 Node.js 版本上运行测试
|
|
49
|
+
3. 执行代码质量检查
|
|
50
|
+
4. 构建包并验证
|
|
51
|
+
|
|
52
|
+
### 版本管理流程
|
|
53
|
+
1. 当 package.json 版本变更时触发
|
|
54
|
+
2. 自动创建 GitHub Release
|
|
55
|
+
3. 生成基于提交历史的 changelog
|
|
56
|
+
|
|
57
|
+
### 发布流程
|
|
58
|
+
1. 当创建 GitHub Release 时触发
|
|
59
|
+
2. 使用 OIDC 进行可信认证
|
|
60
|
+
3. 构建并发布到 npm
|
|
61
|
+
4. 生成来源证明(provenance)
|
|
62
|
+
|
|
63
|
+
## 手动发布
|
|
64
|
+
|
|
65
|
+
如果需要手动发布:
|
|
66
|
+
|
|
67
|
+
1. 更新 `package.json` 中的版本号
|
|
68
|
+
2. 提交并推送到 main 分支
|
|
69
|
+
3. 版本管理 workflow 会自动创建 Release
|
|
70
|
+
4. 发布 workflow 会自动发布到 npm
|
|
71
|
+
|
|
72
|
+
或者使用 workflow_dispatch:
|
|
73
|
+
1. 前往 Actions → Publish to npm
|
|
74
|
+
2. 点击 "Run workflow"
|
|
75
|
+
3. 选择分支并运行
|
|
76
|
+
|
|
77
|
+
## 安全注意事项
|
|
78
|
+
|
|
79
|
+
1. **令牌安全**:
|
|
80
|
+
- 永远不要在代码中硬编码令牌
|
|
81
|
+
- 使用 GitHub Secrets 存储敏感信息
|
|
82
|
+
- 定期轮换令牌
|
|
83
|
+
|
|
84
|
+
2. **OIDC 优势**:
|
|
85
|
+
- 消除长期令牌的管理
|
|
86
|
+
- 自动化的短期会话令牌
|
|
87
|
+
- 更好的安全审计
|
|
88
|
+
|
|
89
|
+
3. **来源证明**:
|
|
90
|
+
- 使用 `--provenance` 标志发布
|
|
91
|
+
- 验证包的构建环境和来源
|
|
92
|
+
- 增加用户信任
|
|
93
|
+
|
|
94
|
+
## 故障排除
|
|
95
|
+
|
|
96
|
+
### 常见问题
|
|
97
|
+
|
|
98
|
+
1. **认证失败**:
|
|
99
|
+
- 确保仓库启用了 OIDC 支持
|
|
100
|
+
- 检查 workflow 中设置了 `permissions: id-token: write`
|
|
101
|
+
- 验证 npm 版本是否支持 OIDC(需要 npm 9.0.0+)
|
|
102
|
+
|
|
103
|
+
2. **版本检测失败**:
|
|
104
|
+
- 确保 `fetch-depth: 0` 以获取完整历史
|
|
105
|
+
- 检查 package.json 格式是否正确
|
|
106
|
+
|
|
107
|
+
3. **构建失败**:
|
|
108
|
+
- 检查 Node.js 版本兼容性
|
|
109
|
+
- 验证 TypeScript 配置
|
|
110
|
+
- 确保所有依赖项已安装
|
|
111
|
+
|
|
112
|
+
### 调试
|
|
113
|
+
- 查看 GitHub Actions 日志
|
|
114
|
+
- 启用调试日志:在仓库 Settings → Actions → Runner 中设置 secret `ACTIONS_STEP_DEBUG` 为 `true`
|
|
115
|
+
|
|
116
|
+
## 相关链接
|
|
117
|
+
|
|
118
|
+
- [npm 认证变更公告](https://github.blog/changelog/2025-12-09-npm-classic-tokens-revoked-session-based-auth-and-cli-token-management-now-available/)
|
|
119
|
+
- [GitHub Actions npm 发布文档](https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages)
|
|
120
|
+
- [npm 可信发布文档](https://docs.npmjs.com/trusted-publishing-with-oidc)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# GitHub Pages 部署配置
|
|
2
|
+
|
|
3
|
+
此目录包含 ZEN 项目文档站点的 GitHub Pages 部署配置。
|
|
4
|
+
|
|
5
|
+
## 工作流程
|
|
6
|
+
|
|
7
|
+
### `pages.yml`
|
|
8
|
+
|
|
9
|
+
此工作流程会自动构建 ZEN 项目的文档站点并部署到 GitHub Pages。
|
|
10
|
+
|
|
11
|
+
**触发条件:**
|
|
12
|
+
- 推送到 `main` 分支(当 `demo/src/`、`package.json` 或工作流程文件发生变化时)
|
|
13
|
+
- 针对 `main` 分支的 Pull Request
|
|
14
|
+
- 手动触发
|
|
15
|
+
|
|
16
|
+
**工作流程步骤:**
|
|
17
|
+
|
|
18
|
+
1. **检出代码**:从远程分支检出代码,确保代码同步
|
|
19
|
+
2. **设置 Node.js**:配置 Node.js 20.x 环境
|
|
20
|
+
3. **安装依赖**:使用 `npm ci` 安装项目依赖
|
|
21
|
+
4. **构建 zengen**:构建本地 zengen 包
|
|
22
|
+
5. **安装 zengen**:将本地构建的 zengen 安装为全局工具
|
|
23
|
+
6. **测试 zengen CLI**:验证 CLI 工具正常工作
|
|
24
|
+
7. **构建文档站点**:使用 `zengen build demo/src --out docs-dist` 构建文档,包含自动回退机制
|
|
25
|
+
7. **配置 Pages**:设置 GitHub Pages
|
|
26
|
+
8. **上传制品**:将构建的文档站点上传为 Pages 制品
|
|
27
|
+
9. **部署到 GitHub Pages**:自动部署到 GitHub Pages
|
|
28
|
+
|
|
29
|
+
## 访问文档站点
|
|
30
|
+
|
|
31
|
+
部署成功后,文档站点将可通过以下 URL 访问:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
https://[用户名].github.io/[仓库名]/
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 自定义配置
|
|
38
|
+
|
|
39
|
+
### 自定义域名
|
|
40
|
+
|
|
41
|
+
如果需要使用自定义域名,可以在构建步骤后添加 CNAME 文件:
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
# 创建 CNAME 文件(如果需要自定义域名)
|
|
45
|
+
echo "docs.example.com" > docs-dist/CNAME
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 构建选项
|
|
49
|
+
|
|
50
|
+
当前使用的构建命令:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
zengen build demo/src --out docs-dist --clean --verbose
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
可用的选项:
|
|
57
|
+
- `--clean`:在构建前清理输出目录
|
|
58
|
+
- `--verbose`:显示详细输出
|
|
59
|
+
- `--watch`:监听模式(不适用于 CI/CD)
|
|
60
|
+
- `--template`:指定自定义模板文件
|
|
61
|
+
- `--config`:指定配置文件
|
|
62
|
+
|
|
63
|
+
### 环境变量
|
|
64
|
+
|
|
65
|
+
工作流程使用以下环境变量:
|
|
66
|
+
- `GITHUB_TOKEN`:自动提供的 GitHub 令牌
|
|
67
|
+
- `NODE_VERSION`:Node.js 版本(默认为 20.x)
|
|
68
|
+
|
|
69
|
+
## 故障排除
|
|
70
|
+
|
|
71
|
+
### 构建失败
|
|
72
|
+
|
|
73
|
+
1. **检查 Node.js 版本**:确保使用支持的 Node.js 版本
|
|
74
|
+
2. **验证依赖安装**:确保 `npm ci` 成功执行
|
|
75
|
+
3. **检查构建输出**:查看 `zengen build` 的详细输出
|
|
76
|
+
4. **CLI 输出目录问题**:如果 `--out` 参数未生效,构建可能输出到 `dist` 目录而不是指定目录。工作流程包含自动检测和修复机制。
|
|
77
|
+
|
|
78
|
+
### 部署失败
|
|
79
|
+
|
|
80
|
+
1. **检查权限**:确保工作流程有正确的 Pages 写入权限
|
|
81
|
+
2. **验证制品**:确保 `docs-dist` 目录包含有效的 HTML 文件
|
|
82
|
+
3. **查看日志**:检查 GitHub Actions 日志获取详细错误信息
|
|
83
|
+
|
|
84
|
+
### 文档未更新
|
|
85
|
+
|
|
86
|
+
1. **检查触发条件**:确保修改了 `demo/src/` 目录下的文件
|
|
87
|
+
2. **等待部署完成**:GitHub Pages 部署可能需要几分钟
|
|
88
|
+
3. **清除浏览器缓存**:浏览器可能缓存了旧版本
|
|
89
|
+
|
|
90
|
+
## 手动触发
|
|
91
|
+
|
|
92
|
+
可以通过 GitHub Actions 界面手动触发部署:
|
|
93
|
+
|
|
94
|
+
1. 进入仓库的 "Actions" 标签页
|
|
95
|
+
2. 选择 "Deploy to GitHub Pages" 工作流程
|
|
96
|
+
3. 点击 "Run workflow" 按钮
|
|
97
|
+
4. 选择分支并运行
|
|
98
|
+
|
|
99
|
+
## 相关文件
|
|
100
|
+
|
|
101
|
+
- `demo/src/`:文档源文件(Markdown 格式)
|
|
102
|
+
- `package.json`:项目配置和依赖
|
|
103
|
+
- `src/cli.ts`:zengen CLI 工具实现
|
|
104
|
+
- `src/builder.ts`:文档构建器实现
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
node-version: [18.x, 20.x, 22.x]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Setup Node.js ${{ matrix.node-version }}
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: ${{ matrix.node-version }}
|
|
24
|
+
cache: 'npm'
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Run linting (if configured)
|
|
30
|
+
run: |
|
|
31
|
+
if [ -f .eslintrc.js ] || [ -f .eslintrc.json ] || [ -f .eslintrc ]; then
|
|
32
|
+
npx eslint src/ --ext .ts,.tsx
|
|
33
|
+
else
|
|
34
|
+
echo "No ESLint config found, skipping linting"
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
- name: Type check
|
|
38
|
+
run: npx tsc --noEmit
|
|
39
|
+
|
|
40
|
+
- name: Run tests
|
|
41
|
+
run: npm test
|
|
42
|
+
|
|
43
|
+
- name: Build package
|
|
44
|
+
run: npm run build
|
|
45
|
+
|
|
46
|
+
- name: Verify CLI works
|
|
47
|
+
run: |
|
|
48
|
+
node dist/cli.js --help
|
|
49
|
+
echo "CLI verification successful"
|
|
50
|
+
|
|
51
|
+
security:
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- name: Checkout repository
|
|
55
|
+
uses: actions/checkout@v4
|
|
56
|
+
|
|
57
|
+
- name: Setup Node.js
|
|
58
|
+
uses: actions/setup-node@v4
|
|
59
|
+
with:
|
|
60
|
+
node-version: '20.x'
|
|
61
|
+
|
|
62
|
+
- name: Install dependencies
|
|
63
|
+
run: npm ci
|
|
64
|
+
|
|
65
|
+
- name: Run npm audit
|
|
66
|
+
run: npm audit --audit-level=moderate
|
|
67
|
+
|
|
68
|
+
- name: Check for outdated dependencies
|
|
69
|
+
run: npm outdated || true
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
name: Deploy to GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- 'demo/src/**'
|
|
8
|
+
- 'package.json'
|
|
9
|
+
- '.github/workflows/pages.yml'
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [main]
|
|
12
|
+
paths:
|
|
13
|
+
- 'demo/src/**'
|
|
14
|
+
- 'package.json'
|
|
15
|
+
- '.github/workflows/pages.yml'
|
|
16
|
+
workflow_dispatch: # 允许手动触发
|
|
17
|
+
|
|
18
|
+
# 设置 GITHUB_TOKEN 的权限以允许部署到 GitHub Pages
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
pages: write
|
|
22
|
+
id-token: write
|
|
23
|
+
|
|
24
|
+
# 只允许一个并发部署,跳过正在运行的队列
|
|
25
|
+
concurrency:
|
|
26
|
+
group: "pages"
|
|
27
|
+
cancel-in-progress: false
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
build:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- name: Checkout repository
|
|
34
|
+
uses: actions/checkout@v4
|
|
35
|
+
with:
|
|
36
|
+
# 从远程分支开始时,需要先同步分支保证代码正确
|
|
37
|
+
fetch-depth: 0
|
|
38
|
+
ref: ${{ github.head_ref || github.ref }}
|
|
39
|
+
|
|
40
|
+
- name: Setup Node.js
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: '20.x'
|
|
44
|
+
cache: 'npm'
|
|
45
|
+
|
|
46
|
+
- name: Install dependencies
|
|
47
|
+
run: npm ci
|
|
48
|
+
|
|
49
|
+
- name: Build zengen package
|
|
50
|
+
run: npm run build
|
|
51
|
+
|
|
52
|
+
- name: Install zengen globally (from local build)
|
|
53
|
+
run: |
|
|
54
|
+
# 从本地构建安装 zengen
|
|
55
|
+
npm install -g .
|
|
56
|
+
# 验证安装
|
|
57
|
+
zengen --version
|
|
58
|
+
|
|
59
|
+
- name: Test zengen CLI
|
|
60
|
+
run: |
|
|
61
|
+
# 测试 CLI 命令
|
|
62
|
+
echo "Testing zengen CLI..."
|
|
63
|
+
zengen --help
|
|
64
|
+
zengen build --help
|
|
65
|
+
|
|
66
|
+
- name: Create documentation site
|
|
67
|
+
run: |
|
|
68
|
+
# 使用 zengen 构建文档站点
|
|
69
|
+
echo "Building documentation site from demo/src..."
|
|
70
|
+
|
|
71
|
+
# 首先清理可能存在的旧输出(保留 dist 目录中的 CLI 文件)
|
|
72
|
+
rm -rf docs-dist
|
|
73
|
+
# 只删除 dist 目录中的 HTML 文件,保留 CLI 文件
|
|
74
|
+
find dist -name "*.html" -delete 2>/dev/null || true
|
|
75
|
+
find dist -name "*.json" -delete 2>/dev/null || true
|
|
76
|
+
find dist -name "*.xml" -delete 2>/dev/null || true
|
|
77
|
+
|
|
78
|
+
# 使用 zengen 构建
|
|
79
|
+
zengen build demo/src --out docs-dist --clean --verbose
|
|
80
|
+
|
|
81
|
+
# 检查构建结果
|
|
82
|
+
echo "Checking build output..."
|
|
83
|
+
if [ -d "docs-dist" ] && [ -f "docs-dist/index.html" ]; then
|
|
84
|
+
echo "✅ Build successful - docs-dist directory exists with index.html"
|
|
85
|
+
ls -la docs-dist/
|
|
86
|
+
else
|
|
87
|
+
echo "⚠️ Build may have output to dist directory instead"
|
|
88
|
+
if [ -d "dist" ] && [ -f "dist/index.html" ]; then
|
|
89
|
+
echo "Found output in dist directory, copying to docs-dist"
|
|
90
|
+
cp -r dist docs-dist
|
|
91
|
+
ls -la docs-dist/
|
|
92
|
+
else
|
|
93
|
+
echo "❌ Build failed - no output found"
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# 创建 CNAME 文件(如果需要自定义域名)
|
|
99
|
+
# echo "docs.example.com" > docs-dist/CNAME
|
|
100
|
+
|
|
101
|
+
- name: Setup Pages
|
|
102
|
+
uses: actions/configure-pages@v4
|
|
103
|
+
|
|
104
|
+
- name: Upload artifact
|
|
105
|
+
uses: actions/upload-pages-artifact@v3
|
|
106
|
+
with:
|
|
107
|
+
path: './docs-dist'
|
|
108
|
+
|
|
109
|
+
deploy:
|
|
110
|
+
environment:
|
|
111
|
+
name: github-pages
|
|
112
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
113
|
+
runs-on: ubuntu-latest
|
|
114
|
+
needs: build
|
|
115
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
116
|
+
steps:
|
|
117
|
+
- name: Deploy to GitHub Pages
|
|
118
|
+
id: deployment
|
|
119
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch: # 允许手动触发
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
id-token: write # 必需:用于 OIDC 认证
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish-npm:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 0
|
|
21
|
+
|
|
22
|
+
- name: Fetch all branches and tags
|
|
23
|
+
run: |
|
|
24
|
+
git fetch --all
|
|
25
|
+
git fetch --tags
|
|
26
|
+
|
|
27
|
+
- name: Setup Node.js for npm publish
|
|
28
|
+
uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: '20.x'
|
|
31
|
+
registry-url: 'https://registry.npmjs.org'
|
|
32
|
+
cache: 'npm'
|
|
33
|
+
|
|
34
|
+
- name: Update npm to latest version
|
|
35
|
+
run: npm install -g npm@latest
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: npm ci
|
|
39
|
+
|
|
40
|
+
- name: Run tests
|
|
41
|
+
run: npm test
|
|
42
|
+
|
|
43
|
+
- name: Build package
|
|
44
|
+
run: npm run build
|
|
45
|
+
|
|
46
|
+
- name: Verify build
|
|
47
|
+
run: |
|
|
48
|
+
ls -la dist/
|
|
49
|
+
test -f dist/index.js && test -f dist/cli.js
|
|
50
|
+
echo "Build verification successful"
|
|
51
|
+
|
|
52
|
+
- name: Check if version already published
|
|
53
|
+
id: check_version
|
|
54
|
+
run: |
|
|
55
|
+
# 获取当前 package.json 中的版本和包名
|
|
56
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
57
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
58
|
+
echo "Package name: $PACKAGE_NAME"
|
|
59
|
+
echo "Current version in package.json: $CURRENT_VERSION"
|
|
60
|
+
|
|
61
|
+
# 尝试从 npm 获取已发布的版本信息
|
|
62
|
+
if npm view $PACKAGE_NAME@$CURRENT_VERSION version > /dev/null 2>&1; then
|
|
63
|
+
echo "Version $CURRENT_VERSION is already published on npm"
|
|
64
|
+
echo "skip_publish=true" >> $GITHUB_OUTPUT
|
|
65
|
+
else
|
|
66
|
+
echo "Version $CURRENT_VERSION is not published yet"
|
|
67
|
+
echo "skip_publish=false" >> $GITHUB_OUTPUT
|
|
68
|
+
fi
|
|
69
|
+
env:
|
|
70
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
71
|
+
|
|
72
|
+
- name: Check npm version
|
|
73
|
+
run: npm --version
|
|
74
|
+
|
|
75
|
+
- name: Publish to npm
|
|
76
|
+
if: steps.check_version.outputs.skip_publish == 'false'
|
|
77
|
+
run: |
|
|
78
|
+
echo "Attempting to publish to npm..."
|
|
79
|
+
npm publish --access public
|
|
80
|
+
env:
|
|
81
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: Version Management
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- 'package.json'
|
|
8
|
+
- 'src/**'
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
check-version:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
outputs:
|
|
14
|
+
version_changed: ${{ steps.check.outputs.version_changed }}
|
|
15
|
+
new_version: ${{ steps.check.outputs.new_version }}
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 0
|
|
21
|
+
|
|
22
|
+
- name: Check if version changed
|
|
23
|
+
id: check
|
|
24
|
+
run: |
|
|
25
|
+
# 获取当前版本
|
|
26
|
+
CURRENT_VERSION=$(jq -r '.version' package.json)
|
|
27
|
+
echo "Current version: $CURRENT_VERSION"
|
|
28
|
+
|
|
29
|
+
# 获取上一个提交的版本
|
|
30
|
+
git checkout HEAD~1 package.json 2>/dev/null || true
|
|
31
|
+
PREVIOUS_VERSION=$(jq -r '.version' package.json 2>/dev/null || echo "0.0.0")
|
|
32
|
+
git checkout HEAD package.json
|
|
33
|
+
|
|
34
|
+
echo "Previous version: $PREVIOUS_VERSION"
|
|
35
|
+
|
|
36
|
+
if [ "$CURRENT_VERSION" != "$PREVIOUS_VERSION" ]; then
|
|
37
|
+
echo "Version changed from $PREVIOUS_VERSION to $CURRENT_VERSION"
|
|
38
|
+
echo "version_changed=true" >> $GITHUB_OUTPUT
|
|
39
|
+
echo "new_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
|
40
|
+
else
|
|
41
|
+
echo "Version unchanged"
|
|
42
|
+
echo "version_changed=false" >> $GITHUB_OUTPUT
|
|
43
|
+
echo "new_version=" >> $GITHUB_OUTPUT
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
create-release:
|
|
47
|
+
needs: check-version
|
|
48
|
+
if: needs.check-version.outputs.version_changed == 'true'
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
steps:
|
|
51
|
+
- name: Checkout repository
|
|
52
|
+
uses: actions/checkout@v4
|
|
53
|
+
with:
|
|
54
|
+
fetch-depth: 0
|
|
55
|
+
|
|
56
|
+
- name: Setup Node.js
|
|
57
|
+
uses: actions/setup-node@v4
|
|
58
|
+
with:
|
|
59
|
+
node-version: '20.x'
|
|
60
|
+
|
|
61
|
+
- name: Get version and changelog
|
|
62
|
+
id: get_info
|
|
63
|
+
run: |
|
|
64
|
+
VERSION=$(jq -r '.version' package.json)
|
|
65
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
66
|
+
|
|
67
|
+
# 尝试获取最近的提交信息作为发布说明
|
|
68
|
+
CHANGELOG=$(git log --oneline -n 10 --grep="^feat\|^fix\|^chore\|^docs\|^style\|^refactor\|^test\|^perf" || echo "No significant changes found")
|
|
69
|
+
echo "changelog<<EOF" >> $GITHUB_OUTPUT
|
|
70
|
+
echo "$CHANGELOG" >> $GITHUB_OUTPUT
|
|
71
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
72
|
+
|
|
73
|
+
- name: Create GitHub Release
|
|
74
|
+
uses: softprops/action-gh-release@v1
|
|
75
|
+
with:
|
|
76
|
+
tag_name: v${{ steps.get_info.outputs.version }}
|
|
77
|
+
name: Release v${{ steps.get_info.outputs.version }}
|
|
78
|
+
body: |
|
|
79
|
+
## Changes in v${{ steps.get_info.outputs.version }}
|
|
80
|
+
|
|
81
|
+
${{ steps.get_info.outputs.changelog }}
|
|
82
|
+
|
|
83
|
+
### Automated Release
|
|
84
|
+
This release was automatically created when the package version was updated.
|
|
85
|
+
draft: false
|
|
86
|
+
prerelease: false
|
|
87
|
+
env:
|
|
88
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
package/dist/builder.d.ts
CHANGED
package/dist/builder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA4B,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA4B,SAAS,EAAE,MAAM,SAAS,CAAC;AAU5E,qBAAa,UAAU;IACrB,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,GAAE,SAAc;IAOlC;;OAEG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAqFjD;;OAEG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoGjD;;OAEG;YACW,eAAe;IAsB7B;;OAEG;YACW,eAAe;IAU7B;;OAEG;YACW,sBAAsB;IAUpC;;OAEG;YACW,gBAAgB;IA6B9B;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE;CAuB5C"}
|
package/dist/builder.js
CHANGED
|
@@ -32,6 +32,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.ZenBuilder = void 0;
|
|
37
40
|
const markdown_1 = require("./markdown");
|
|
@@ -40,6 +43,7 @@ const navigation_1 = require("./navigation");
|
|
|
40
43
|
const fs = __importStar(require("fs/promises"));
|
|
41
44
|
const path = __importStar(require("path"));
|
|
42
45
|
const chokidar = __importStar(require("chokidar"));
|
|
46
|
+
const express_1 = __importDefault(require("express"));
|
|
43
47
|
class ZenBuilder {
|
|
44
48
|
constructor(config = {}) {
|
|
45
49
|
this.config = {};
|
|
@@ -130,11 +134,17 @@ class ZenBuilder {
|
|
|
130
134
|
* 监听文件变化并自动重建
|
|
131
135
|
*/
|
|
132
136
|
async watch(options) {
|
|
133
|
-
const { srcDir, outDir, template, verbose = false } = options;
|
|
137
|
+
const { srcDir, outDir, template, verbose = false, serve = false, port = 3000, host = 'localhost' } = options;
|
|
134
138
|
console.log(`👀 Watching for changes in ${srcDir}...`);
|
|
135
139
|
console.log(`Press Ctrl+C to stop watching`);
|
|
136
140
|
// 初始构建
|
|
137
141
|
await this.build(options);
|
|
142
|
+
// 启动 HTTP 服务器(如果启用)
|
|
143
|
+
let server = null;
|
|
144
|
+
if (serve) {
|
|
145
|
+
server = await this.startHttpServer(outDir, port, host);
|
|
146
|
+
console.log(`🌐 HTTP server started at http://${host}:${port}`);
|
|
147
|
+
}
|
|
138
148
|
// 设置文件监听
|
|
139
149
|
const watcher = chokidar.watch(srcDir, {
|
|
140
150
|
ignored: /(^|[\/\\])\../, // 忽略隐藏文件
|
|
@@ -203,7 +213,37 @@ class ZenBuilder {
|
|
|
203
213
|
process.on('SIGINT', () => {
|
|
204
214
|
console.log(`\n👋 Stopping watcher...`);
|
|
205
215
|
watcher.close();
|
|
206
|
-
|
|
216
|
+
// 关闭 HTTP 服务器(如果存在)
|
|
217
|
+
if (server) {
|
|
218
|
+
console.log(`🌐 Stopping HTTP server...`);
|
|
219
|
+
server.close(() => {
|
|
220
|
+
console.log(`✅ HTTP server stopped`);
|
|
221
|
+
process.exit(0);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
process.exit(0);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 启动 HTTP 服务器
|
|
231
|
+
*/
|
|
232
|
+
async startHttpServer(outDir, port, host) {
|
|
233
|
+
return new Promise((resolve, reject) => {
|
|
234
|
+
const app = (0, express_1.default)();
|
|
235
|
+
// 提供静态文件服务
|
|
236
|
+
app.use(express_1.default.static(outDir));
|
|
237
|
+
// 处理 SPA 路由 - 所有未找到的路径返回 index.html
|
|
238
|
+
app.get('*', (req, res) => {
|
|
239
|
+
res.sendFile(path.join(outDir, 'index.html'));
|
|
240
|
+
});
|
|
241
|
+
const server = app.listen(port, host, () => {
|
|
242
|
+
resolve(server);
|
|
243
|
+
});
|
|
244
|
+
server.on('error', (error) => {
|
|
245
|
+
reject(error);
|
|
246
|
+
});
|
|
207
247
|
});
|
|
208
248
|
}
|
|
209
249
|
/**
|
package/dist/builder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -38,11 +38,16 @@ const commander_1 = require("commander");
|
|
|
38
38
|
const builder_1 = require("./builder");
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
40
|
const fs = __importStar(require("fs/promises"));
|
|
41
|
+
// 获取版本号 - 从 package.json 读取
|
|
42
|
+
// 注意:在构建时,版本号会被替换为当前 package.json 中的版本
|
|
43
|
+
function getVersion() {
|
|
44
|
+
return '0.1.2'; // 这个值会在构建时被替换
|
|
45
|
+
}
|
|
41
46
|
const program = new commander_1.Command();
|
|
42
47
|
program
|
|
43
48
|
.name('zengen')
|
|
44
49
|
.description('ZEN - A minimalist Markdown documentation site builder')
|
|
45
|
-
.version(
|
|
50
|
+
.version(getVersion());
|
|
46
51
|
// 构建命令
|
|
47
52
|
program
|
|
48
53
|
.command('build')
|
|
@@ -51,6 +56,9 @@ program
|
|
|
51
56
|
.option('-o, --out <dir>', 'Output directory for generated HTML', 'dist')
|
|
52
57
|
.option('-t, --template <file>', 'Custom template file')
|
|
53
58
|
.option('-w, --watch', 'Watch for changes and rebuild automatically')
|
|
59
|
+
.option('-s, --serve', 'Start HTTP server for preview (requires --watch)')
|
|
60
|
+
.option('-p, --port <number>', 'HTTP server port', '3000')
|
|
61
|
+
.option('--host <host>', 'HTTP server host', 'localhost')
|
|
54
62
|
.option('-v, --verbose', 'Show detailed output')
|
|
55
63
|
.option('-c, --config <file>', 'Configuration file')
|
|
56
64
|
.option('--clean', 'Clean output directory before building')
|
|
@@ -75,6 +83,9 @@ program
|
|
|
75
83
|
outDir: path.resolve(options.out),
|
|
76
84
|
template: options.template ? path.resolve(options.template) : undefined,
|
|
77
85
|
watch: options.watch,
|
|
86
|
+
serve: options.serve,
|
|
87
|
+
port: parseInt(options.port, 10),
|
|
88
|
+
host: options.host,
|
|
78
89
|
verbose: options.verbose
|
|
79
90
|
};
|
|
80
91
|
const builder = new builder_1.ZenBuilder(config);
|
|
@@ -85,6 +96,11 @@ program
|
|
|
85
96
|
errors.forEach(error => console.error(` - ${error}`));
|
|
86
97
|
process.exit(1);
|
|
87
98
|
}
|
|
99
|
+
// 警告 --serve 选项需要 --watch 选项
|
|
100
|
+
if (options.serve && !options.watch) {
|
|
101
|
+
console.warn('⚠️ Warning: --serve option requires --watch option, ignoring --serve');
|
|
102
|
+
buildOptions.serve = false;
|
|
103
|
+
}
|
|
88
104
|
// 清理输出目录
|
|
89
105
|
if (options.clean) {
|
|
90
106
|
await builder.clean(buildOptions.outDir);
|
|
@@ -177,6 +193,7 @@ console.log('Hello ZEN!');
|
|
|
177
193
|
}
|
|
178
194
|
packageJson.scripts.build = 'zengen build docs --out dist';
|
|
179
195
|
packageJson.scripts['build:watch'] = 'zengen build docs --out dist --watch';
|
|
196
|
+
packageJson.scripts['build:serve'] = 'zengen build docs --out dist --watch --serve';
|
|
180
197
|
packageJson.scripts.clean = 'zengen clean dist';
|
|
181
198
|
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
182
199
|
}
|
|
@@ -188,6 +205,7 @@ console.log('Hello ZEN!');
|
|
|
188
205
|
scripts: {
|
|
189
206
|
build: 'zengen build docs --out dist',
|
|
190
207
|
'build:watch': 'zengen build docs --out dist --watch',
|
|
208
|
+
'build:serve': 'zengen build docs --out dist --watch --serve',
|
|
191
209
|
clean: 'zengen clean dist'
|
|
192
210
|
}
|
|
193
211
|
};
|
|
@@ -200,6 +218,7 @@ Next steps:
|
|
|
200
218
|
1. Add your Markdown files to the 'docs' directory
|
|
201
219
|
2. Run 'npm run build' to generate the site
|
|
202
220
|
3. Run 'npm run build:watch' for development with auto-reload
|
|
221
|
+
4. Run 'npm run build:serve' for development with auto-reload and HTTP server
|
|
203
222
|
|
|
204
223
|
Project structure:
|
|
205
224
|
${targetDir}/
|
|
@@ -246,6 +265,8 @@ Commands:
|
|
|
246
265
|
Examples:
|
|
247
266
|
$ zengen build ./docs --out ./dist
|
|
248
267
|
$ zengen build ./docs --out ./dist --watch
|
|
268
|
+
$ zengen build ./docs --out ./dist --watch --serve
|
|
269
|
+
$ zengen build ./docs --out ./dist --watch --serve --port 8080
|
|
249
270
|
$ zengen init --dir ./my-docs
|
|
250
271
|
$ zengen clean ./dist
|
|
251
272
|
|
|
@@ -258,6 +279,9 @@ program
|
|
|
258
279
|
.option('-o, --out <dir>', 'Output directory')
|
|
259
280
|
.option('-t, --template <file>', 'Custom template file')
|
|
260
281
|
.option('-w, --watch', 'Watch for changes')
|
|
282
|
+
.option('-s, --serve', 'Start HTTP server for preview (requires --watch)')
|
|
283
|
+
.option('-p, --port <number>', 'HTTP server port', '3000')
|
|
284
|
+
.option('--host <host>', 'HTTP server host', 'localhost')
|
|
261
285
|
.option('-v, --verbose', 'Show detailed output')
|
|
262
286
|
.action(async (srcDir, options) => {
|
|
263
287
|
if (!srcDir) {
|
|
@@ -271,8 +295,16 @@ program
|
|
|
271
295
|
outDir: path.resolve(options.out || 'dist'),
|
|
272
296
|
template: options.template ? path.resolve(options.template) : undefined,
|
|
273
297
|
watch: options.watch,
|
|
298
|
+
serve: options.serve,
|
|
299
|
+
port: parseInt(options.port, 10),
|
|
300
|
+
host: options.host,
|
|
274
301
|
verbose: options.verbose
|
|
275
302
|
};
|
|
303
|
+
// 警告 --serve 选项需要 --watch 选项
|
|
304
|
+
if (options.serve && !options.watch) {
|
|
305
|
+
console.warn('⚠️ Warning: --serve option requires --watch option, ignoring --serve');
|
|
306
|
+
buildOptions.serve = false;
|
|
307
|
+
}
|
|
276
308
|
if (options.watch) {
|
|
277
309
|
await builder.watch(buildOptions);
|
|
278
310
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,uCAAuC;AAEvC,2CAA6B;AAC7B,gDAAkC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5E,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zengen",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "ZEN - A minimalist Markdown documentation site builder",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"dev": "ts-node src/cli.ts",
|
|
13
|
-
"test": "
|
|
13
|
+
"test": "npm run test:types && npm run test:build && npm run test:cli",
|
|
14
|
+
"test:types": "tsc --noEmit",
|
|
15
|
+
"test:build": "npm run build && test -f dist/index.js && test -f dist/cli.js",
|
|
16
|
+
"test:cli": "node -e \"const pkg = require('./package.json'); console.log('Package:', pkg.name, 'v' + pkg.version)\"",
|
|
14
17
|
"prepublishOnly": "npm run build"
|
|
15
18
|
},
|
|
16
19
|
"keywords": [
|
|
@@ -31,6 +34,7 @@
|
|
|
31
34
|
"homepage": "https://github.com/zccz14/ZEN#readme",
|
|
32
35
|
"devDependencies": {
|
|
33
36
|
"@types/chokidar": "^1.7.5",
|
|
37
|
+
"@types/express": "^5.0.6",
|
|
34
38
|
"@types/node": "^25.0.3",
|
|
35
39
|
"@types/yaml": "^1.9.6",
|
|
36
40
|
"ts-node": "^10.9.2",
|
|
@@ -39,6 +43,7 @@
|
|
|
39
43
|
"dependencies": {
|
|
40
44
|
"chokidar": "^5.0.0",
|
|
41
45
|
"commander": "^14.0.2",
|
|
46
|
+
"express": "^4.21.2",
|
|
42
47
|
"highlight.js": "^11.11.1",
|
|
43
48
|
"marked": "^17.0.1",
|
|
44
49
|
"yaml": "^1.10.2"
|
package/src/builder.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { NavigationGenerator } from './navigation';
|
|
|
5
5
|
import * as fs from 'fs/promises';
|
|
6
6
|
import * as path from 'path';
|
|
7
7
|
import * as chokidar from 'chokidar';
|
|
8
|
+
import express from 'express';
|
|
9
|
+
import * as http from 'http';
|
|
8
10
|
|
|
9
11
|
export class ZenBuilder {
|
|
10
12
|
private markdownConverter: MarkdownConverter;
|
|
@@ -111,7 +113,7 @@ export class ZenBuilder {
|
|
|
111
113
|
* 监听文件变化并自动重建
|
|
112
114
|
*/
|
|
113
115
|
async watch(options: BuildOptions): Promise<void> {
|
|
114
|
-
const { srcDir, outDir, template, verbose = false } = options;
|
|
116
|
+
const { srcDir, outDir, template, verbose = false, serve = false, port = 3000, host = 'localhost' } = options;
|
|
115
117
|
|
|
116
118
|
console.log(`👀 Watching for changes in ${srcDir}...`);
|
|
117
119
|
console.log(`Press Ctrl+C to stop watching`);
|
|
@@ -119,6 +121,13 @@ export class ZenBuilder {
|
|
|
119
121
|
// 初始构建
|
|
120
122
|
await this.build(options);
|
|
121
123
|
|
|
124
|
+
// 启动 HTTP 服务器(如果启用)
|
|
125
|
+
let server: http.Server | null = null;
|
|
126
|
+
if (serve) {
|
|
127
|
+
server = await this.startHttpServer(outDir, port, host);
|
|
128
|
+
console.log(`🌐 HTTP server started at http://${host}:${port}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
122
131
|
// 设置文件监听
|
|
123
132
|
const watcher = chokidar.watch(srcDir, {
|
|
124
133
|
ignored: /(^|[\/\\])\../, // 忽略隐藏文件
|
|
@@ -189,7 +198,42 @@ export class ZenBuilder {
|
|
|
189
198
|
process.on('SIGINT', () => {
|
|
190
199
|
console.log(`\n👋 Stopping watcher...`);
|
|
191
200
|
watcher.close();
|
|
192
|
-
|
|
201
|
+
|
|
202
|
+
// 关闭 HTTP 服务器(如果存在)
|
|
203
|
+
if (server) {
|
|
204
|
+
console.log(`🌐 Stopping HTTP server...`);
|
|
205
|
+
server.close(() => {
|
|
206
|
+
console.log(`✅ HTTP server stopped`);
|
|
207
|
+
process.exit(0);
|
|
208
|
+
});
|
|
209
|
+
} else {
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* 启动 HTTP 服务器
|
|
217
|
+
*/
|
|
218
|
+
private async startHttpServer(outDir: string, port: number, host: string): Promise<http.Server> {
|
|
219
|
+
return new Promise((resolve, reject) => {
|
|
220
|
+
const app = express();
|
|
221
|
+
|
|
222
|
+
// 提供静态文件服务
|
|
223
|
+
app.use(express.static(outDir));
|
|
224
|
+
|
|
225
|
+
// 处理 SPA 路由 - 所有未找到的路径返回 index.html
|
|
226
|
+
app.get('*', (req: express.Request, res: express.Response) => {
|
|
227
|
+
res.sendFile(path.join(outDir, 'index.html'));
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const server = app.listen(port, host, () => {
|
|
231
|
+
resolve(server);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
server.on('error', (error: Error) => {
|
|
235
|
+
reject(error);
|
|
236
|
+
});
|
|
193
237
|
});
|
|
194
238
|
}
|
|
195
239
|
|
package/src/cli.ts
CHANGED
|
@@ -5,13 +5,21 @@ import { ZenBuilder } from './builder';
|
|
|
5
5
|
import { ZenConfig } from './types';
|
|
6
6
|
import * as path from 'path';
|
|
7
7
|
import * as fs from 'fs/promises';
|
|
8
|
+
import * as fsSync from 'fs';
|
|
9
|
+
import * as url from 'url';
|
|
10
|
+
|
|
11
|
+
// 获取版本号 - 从 package.json 读取
|
|
12
|
+
// 注意:在构建时,版本号会被替换为当前 package.json 中的版本
|
|
13
|
+
function getVersion(): string {
|
|
14
|
+
return '0.1.2'; // 这个值会在构建时被替换
|
|
15
|
+
}
|
|
8
16
|
|
|
9
17
|
const program = new Command();
|
|
10
18
|
|
|
11
19
|
program
|
|
12
20
|
.name('zengen')
|
|
13
21
|
.description('ZEN - A minimalist Markdown documentation site builder')
|
|
14
|
-
.version(
|
|
22
|
+
.version(getVersion());
|
|
15
23
|
|
|
16
24
|
// 构建命令
|
|
17
25
|
program
|
|
@@ -21,6 +29,9 @@ program
|
|
|
21
29
|
.option('-o, --out <dir>', 'Output directory for generated HTML', 'dist')
|
|
22
30
|
.option('-t, --template <file>', 'Custom template file')
|
|
23
31
|
.option('-w, --watch', 'Watch for changes and rebuild automatically')
|
|
32
|
+
.option('-s, --serve', 'Start HTTP server for preview (requires --watch)')
|
|
33
|
+
.option('-p, --port <number>', 'HTTP server port', '3000')
|
|
34
|
+
.option('--host <host>', 'HTTP server host', 'localhost')
|
|
24
35
|
.option('-v, --verbose', 'Show detailed output')
|
|
25
36
|
.option('-c, --config <file>', 'Configuration file')
|
|
26
37
|
.option('--clean', 'Clean output directory before building')
|
|
@@ -45,9 +56,13 @@ program
|
|
|
45
56
|
outDir: path.resolve(options.out),
|
|
46
57
|
template: options.template ? path.resolve(options.template) : undefined,
|
|
47
58
|
watch: options.watch,
|
|
59
|
+
serve: options.serve,
|
|
60
|
+
port: parseInt(options.port, 10),
|
|
61
|
+
host: options.host,
|
|
48
62
|
verbose: options.verbose
|
|
49
63
|
};
|
|
50
64
|
|
|
65
|
+
|
|
51
66
|
const builder = new ZenBuilder(config);
|
|
52
67
|
|
|
53
68
|
// 验证配置
|
|
@@ -58,6 +73,12 @@ program
|
|
|
58
73
|
process.exit(1);
|
|
59
74
|
}
|
|
60
75
|
|
|
76
|
+
// 警告 --serve 选项需要 --watch 选项
|
|
77
|
+
if (options.serve && !options.watch) {
|
|
78
|
+
console.warn('⚠️ Warning: --serve option requires --watch option, ignoring --serve');
|
|
79
|
+
buildOptions.serve = false;
|
|
80
|
+
}
|
|
81
|
+
|
|
61
82
|
// 清理输出目录
|
|
62
83
|
if (options.clean) {
|
|
63
84
|
await builder.clean(buildOptions.outDir);
|
|
@@ -166,6 +187,7 @@ console.log('Hello ZEN!');
|
|
|
166
187
|
|
|
167
188
|
packageJson.scripts.build = 'zengen build docs --out dist';
|
|
168
189
|
packageJson.scripts['build:watch'] = 'zengen build docs --out dist --watch';
|
|
190
|
+
packageJson.scripts['build:serve'] = 'zengen build docs --out dist --watch --serve';
|
|
169
191
|
packageJson.scripts.clean = 'zengen clean dist';
|
|
170
192
|
|
|
171
193
|
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
@@ -177,6 +199,7 @@ console.log('Hello ZEN!');
|
|
|
177
199
|
scripts: {
|
|
178
200
|
build: 'zengen build docs --out dist',
|
|
179
201
|
'build:watch': 'zengen build docs --out dist --watch',
|
|
202
|
+
'build:serve': 'zengen build docs --out dist --watch --serve',
|
|
180
203
|
clean: 'zengen clean dist'
|
|
181
204
|
}
|
|
182
205
|
};
|
|
@@ -195,6 +218,7 @@ Next steps:
|
|
|
195
218
|
1. Add your Markdown files to the 'docs' directory
|
|
196
219
|
2. Run 'npm run build' to generate the site
|
|
197
220
|
3. Run 'npm run build:watch' for development with auto-reload
|
|
221
|
+
4. Run 'npm run build:serve' for development with auto-reload and HTTP server
|
|
198
222
|
|
|
199
223
|
Project structure:
|
|
200
224
|
${targetDir}/
|
|
@@ -241,6 +265,8 @@ Commands:
|
|
|
241
265
|
Examples:
|
|
242
266
|
$ zengen build ./docs --out ./dist
|
|
243
267
|
$ zengen build ./docs --out ./dist --watch
|
|
268
|
+
$ zengen build ./docs --out ./dist --watch --serve
|
|
269
|
+
$ zengen build ./docs --out ./dist --watch --serve --port 8080
|
|
244
270
|
$ zengen init --dir ./my-docs
|
|
245
271
|
$ zengen clean ./dist
|
|
246
272
|
|
|
@@ -254,6 +280,9 @@ program
|
|
|
254
280
|
.option('-o, --out <dir>', 'Output directory')
|
|
255
281
|
.option('-t, --template <file>', 'Custom template file')
|
|
256
282
|
.option('-w, --watch', 'Watch for changes')
|
|
283
|
+
.option('-s, --serve', 'Start HTTP server for preview (requires --watch)')
|
|
284
|
+
.option('-p, --port <number>', 'HTTP server port', '3000')
|
|
285
|
+
.option('--host <host>', 'HTTP server host', 'localhost')
|
|
257
286
|
.option('-v, --verbose', 'Show detailed output')
|
|
258
287
|
.action(async (srcDir, options) => {
|
|
259
288
|
if (!srcDir) {
|
|
@@ -269,9 +298,18 @@ program
|
|
|
269
298
|
outDir: path.resolve(options.out || 'dist'),
|
|
270
299
|
template: options.template ? path.resolve(options.template) : undefined,
|
|
271
300
|
watch: options.watch,
|
|
301
|
+
serve: options.serve,
|
|
302
|
+
port: parseInt(options.port, 10),
|
|
303
|
+
host: options.host,
|
|
272
304
|
verbose: options.verbose
|
|
273
305
|
};
|
|
274
306
|
|
|
307
|
+
// 警告 --serve 选项需要 --watch 选项
|
|
308
|
+
if (options.serve && !options.watch) {
|
|
309
|
+
console.warn('⚠️ Warning: --serve option requires --watch option, ignoring --serve');
|
|
310
|
+
buildOptions.serve = false;
|
|
311
|
+
}
|
|
312
|
+
|
|
275
313
|
if (options.watch) {
|
|
276
314
|
await builder.watch(buildOptions);
|
|
277
315
|
} else {
|