speccore 8.3.290 → 8.3.296

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.
Files changed (101) hide show
  1. package/README.en.md +16 -3
  2. package/README.md +9 -7
  3. package/dist/cli.js +11 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/about.d.ts.map +1 -1
  6. package/dist/commands/about.js +5 -0
  7. package/dist/commands/about.js.map +1 -1
  8. package/dist/commands/analyze.d.ts.map +1 -1
  9. package/dist/commands/analyze.js +77 -5
  10. package/dist/commands/analyze.js.map +1 -1
  11. package/dist/commands/ask.js +2 -2
  12. package/dist/commands/ask.js.map +1 -1
  13. package/dist/commands/execute.js +1 -0
  14. package/dist/commands/execute.js.map +1 -1
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +25 -4
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/iteration/taskify.d.ts.map +1 -1
  19. package/dist/commands/iteration/taskify.js +132 -7
  20. package/dist/commands/iteration/taskify.js.map +1 -1
  21. package/dist/commands/status-panel.d.ts +1 -0
  22. package/dist/commands/status-panel.d.ts.map +1 -1
  23. package/dist/commands/status-panel.js +65 -17
  24. package/dist/commands/status-panel.js.map +1 -1
  25. package/dist/commands/update-env-configs.d.ts.map +1 -1
  26. package/dist/commands/update-env-configs.js +6 -0
  27. package/dist/commands/update-env-configs.js.map +1 -1
  28. package/dist/commands/verify.d.ts.map +1 -1
  29. package/dist/commands/verify.js +78 -1
  30. package/dist/commands/verify.js.map +1 -1
  31. package/dist/core/deploy/engine.d.ts +11 -0
  32. package/dist/core/deploy/engine.d.ts.map +1 -1
  33. package/dist/core/deploy/engine.js +35 -7
  34. package/dist/core/deploy/engine.js.map +1 -1
  35. package/dist/core/git-integration.d.ts +2 -1
  36. package/dist/core/git-integration.d.ts.map +1 -1
  37. package/dist/core/git-integration.js +38 -14
  38. package/dist/core/git-integration.js.map +1 -1
  39. package/dist/core/global-counters.d.ts +3 -0
  40. package/dist/core/global-counters.d.ts.map +1 -1
  41. package/dist/core/global-counters.js +3 -1
  42. package/dist/core/global-counters.js.map +1 -1
  43. package/dist/core/prompt-builder.d.ts.map +1 -1
  44. package/dist/core/prompt-builder.js +7 -6
  45. package/dist/core/prompt-builder.js.map +1 -1
  46. package/dist/core/spec-paths.d.ts.map +1 -1
  47. package/dist/core/spec-paths.js +3 -0
  48. package/dist/core/spec-paths.js.map +1 -1
  49. package/dist/core/spec-skeleton.d.ts.map +1 -1
  50. package/dist/core/spec-skeleton.js +6 -2
  51. package/dist/core/spec-skeleton.js.map +1 -1
  52. package/dist/core/state.d.ts +11 -0
  53. package/dist/core/state.d.ts.map +1 -1
  54. package/dist/core/state.js +33 -2
  55. package/dist/core/state.js.map +1 -1
  56. package/dist/core/ui-verify/index.d.ts +2 -2
  57. package/dist/core/ui-verify/index.d.ts.map +1 -1
  58. package/dist/core/ui-verify/index.js +3 -1
  59. package/dist/core/ui-verify/index.js.map +1 -1
  60. package/dist/core/ui-verify/smoke-engine.d.ts.map +1 -1
  61. package/dist/core/ui-verify/smoke-engine.js +36 -0
  62. package/dist/core/ui-verify/smoke-engine.js.map +1 -1
  63. package/dist/core/ui-verify/spec-generator.d.ts +32 -1
  64. package/dist/core/ui-verify/spec-generator.d.ts.map +1 -1
  65. package/dist/core/ui-verify/spec-generator.js +205 -21
  66. package/dist/core/ui-verify/spec-generator.js.map +1 -1
  67. package/dist/core/ui-verify/types.d.ts +2 -0
  68. package/dist/core/ui-verify/types.d.ts.map +1 -1
  69. package/package.json +3 -2
  70. package/templates/api-design-example.md +338 -0
  71. package/templates/ci/github-actions.yml +44 -0
  72. package/templates/database-example.md +223 -0
  73. package/templates/deploy-docker/README.md +296 -0
  74. package/templates/deploy-docker/backend-node.Dockerfile +52 -0
  75. package/templates/deploy-docker/deploy-remote.sh +79 -0
  76. package/templates/deploy-docker/docker-compose.yml +113 -0
  77. package/templates/deploy-docker/frontend.Dockerfile +43 -0
  78. package/templates/deploy-docker/nginx.conf +30 -0
  79. package/templates/deploy-examples.yaml +511 -0
  80. package/templates/deploy-java/Dockerfile +50 -0
  81. package/templates/deploy-java/README.md +212 -0
  82. package/templates/deploy-java/deploy.sh +120 -0
  83. package/templates/deploy-java/spring-boot.service +35 -0
  84. package/templates/deploy-nginx/README.md +59 -0
  85. package/templates/deploy-nginx/nginx-site.conf +103 -0
  86. package/templates/deploy-scripts/README.md +61 -0
  87. package/templates/deploy-scripts/deploy-compose.sh +19 -0
  88. package/templates/deploy-scripts/deploy-ftp.sh +28 -0
  89. package/templates/deploy-scripts/deploy-password-ssh.sh +26 -0
  90. package/templates/deploy-scripts/deploy-python.sh +30 -0
  91. package/templates/deploy-scripts/trigger-jenkins.sh +30 -0
  92. package/templates/html/speccore-ask-explain.html +10 -0
  93. package/templates/html/speccore-ask-guide.html +10 -0
  94. package/templates/html/speccore-ask-match.html +10 -0
  95. package/templates/html/speccore-ask-pipeline.html +1 -0
  96. package/templates/html/speccore-ask-result.html +10 -0
  97. package/templates/html/speccore-help.html +241 -0
  98. package/templates/html/speccore-setup-guide.html +289 -0
  99. package/templates/security-example.md +226 -0
  100. package/templates/speccore-yml-example.yml +222 -0
  101. package/templates/verify-spec-example.yaml +142 -0
@@ -0,0 +1,212 @@
1
+ # Java 后端部署指南
2
+
3
+ > 本目录提供 Java(Spring Boot)后端服务的部署模板和示例脚本。
4
+
5
+ ---
6
+
7
+ ## 目录结构
8
+
9
+ ```
10
+ deploy-java/
11
+ ├── spring-boot.service # systemd service 文件模板
12
+ ├── deploy.sh # 服务器端部署脚本(备份 → 替换 → 重启 → 健康检查)
13
+ ├── Dockerfile # 多阶段构建 Dockerfile 示例
14
+ └── README.md # 本文件
15
+ ```
16
+
17
+ ---
18
+
19
+ ## 部署方式一:systemd + SSH(推荐测试环境)
20
+
21
+ ### 1. 服务器端准备(只需一次)
22
+
23
+ ```bash
24
+ # 创建部署目录
25
+ sudo mkdir -p /opt/services/order-service
26
+ sudo mkdir -p /var/log/order-service
27
+
28
+ # 复制 service 文件(将 spring-boot.service 中的占位符替换后复制)
29
+ # 注意:文件名必须与 PROJECT.yaml 中的 platform.name 一致
30
+ sudo cp spring-boot.service /etc/systemd/system/order-service.service
31
+
32
+ # 重载 systemd
33
+ sudo systemctl daemon-reload
34
+ sudo systemctl enable order-service
35
+ ```
36
+
37
+ ### 2. 替换 service 文件中的占位符
38
+
39
+ | 占位符 | 示例值 | 说明 |
40
+ |--------|--------|------|
41
+ | `{{APP_NAME}}` | `order-service` | 应用名,与 platform.name 一致 |
42
+ | `{{DEPLOY_USER}}` | `deployer` | 运行服务的系统用户 |
43
+ | `{{DEPLOY_DIR}}` | `/opt/services/order-service` | jar 文件所在目录 |
44
+ | `{{PROFILE}}` | `staging` | Spring Boot profile |
45
+ | `{{JVM_XMS}}` | `512m` | JVM 初始堆内存 |
46
+ | `{{JVM_XMX}}` | `1024m` | JVM 最大堆内存 |
47
+
48
+ ### 3. PROJECT.yaml 配置
49
+
50
+ ```yaml
51
+ platforms:
52
+ - name: order-service
53
+ type: backend
54
+ code_path: ./order-service
55
+ default_branch: main
56
+ deploy:
57
+ staging:
58
+ type: ssh
59
+ build_cmd: mvn clean package -DskipTests -P staging
60
+ output_dir: target
61
+ host: deployer@staging-server.example.com:22
62
+ key: ~/.ssh/id_rsa
63
+ remote_dir: /opt/services/order-service
64
+ script: sudo systemctl restart order-service
65
+ ```
66
+
67
+ ### 4. 数据库 / Redis 配置切换
68
+
69
+ **方式 A:Spring Boot Profiles(推荐)**
70
+
71
+ ```yaml
72
+ # src/main/resources/application-staging.yml
73
+ spring:
74
+ datasource:
75
+ url: jdbc:mysql://staging-db:3306/order_db
76
+ username: ${DB_USER}
77
+ password: ${DB_PASS}
78
+ data:
79
+ redis:
80
+ host: staging-redis
81
+ port: 6379
82
+ password: ${REDIS_PASS}
83
+ ```
84
+
85
+ **方式 B:环境变量注入(配合 systemd)**
86
+
87
+ 在 `spring-boot.service` 的 `[Service]` 段增加:
88
+ ```ini
89
+ Environment="DB_USER=order_user"
90
+ Environment="DB_PASS=secret"
91
+ Environment="REDIS_PASS=redis_secret"
92
+ ```
93
+
94
+ 在 `application.yml` 中引用:
95
+ ```yaml
96
+ spring:
97
+ datasource:
98
+ username: ${DB_USER}
99
+ password: ${DB_PASS}
100
+ ```
101
+
102
+ ### 5. 部署流程
103
+
104
+ ```bash
105
+ speccore deploy --env staging --platform order-service
106
+ ```
107
+
108
+ 执行流程:
109
+ 1. 本地执行 `mvn clean package -DskipTests -P staging`
110
+ 2. SCP 上传 `target/*.jar` 到服务器 `/opt/services/order-service/`
111
+ 3. SSH 执行 `sudo systemctl restart order-service`
112
+ 4. systemd 自动完成:停止旧进程 → 启动新 jar → 写入日志
113
+
114
+ ---
115
+
116
+ ## 部署方式二:Docker(推荐生产环境)
117
+
118
+ ### 1. 准备 Dockerfile
119
+
120
+ 将 `Dockerfile` 复制到 Java 工程根目录(与 `pom.xml` 同级)。
121
+
122
+ ### 2. PROJECT.yaml 配置
123
+
124
+ ```yaml
125
+ platforms:
126
+ - name: order-service
127
+ type: backend
128
+ code_path: ./order-service
129
+ default_branch: main
130
+ deploy:
131
+ production:
132
+ type: docker
133
+ dockerfile: ./Dockerfile
134
+ registry: registry.example.com
135
+ image: my-project/order-service
136
+ tag: production
137
+ ```
138
+
139
+ ### 3. 部署流程
140
+
141
+ ```bash
142
+ speccore deploy --env production --platform order-service
143
+ ```
144
+
145
+ 执行流程:
146
+ 1. 本地 `docker build`
147
+ 2. 推送到镜像仓库 `registry.example.com/my-project/order-service:production`
148
+ 3. 服务器端拉取镜像并运行(需配合额外的部署脚本或 CI/CD)
149
+
150
+ > 提示:如果服务器需要 SSH 登录后执行 `docker pull && docker run`,可将 deploy 类型改为 `script`,编写自定义脚本。
151
+
152
+ ---
153
+
154
+ ## 部署方式三:自定义脚本(最灵活)
155
+
156
+ 如果 systemd 和 Docker 都不满足需求,使用 `script` 类型:
157
+
158
+ ```yaml
159
+ deploy:
160
+ staging:
161
+ type: script
162
+ build_cmd: mvn clean package -DskipTests
163
+ script: ./scripts/deploy-custom.sh
164
+ ```
165
+
166
+ ---
167
+
168
+ ## 数据库 / Redis 连接检查清单
169
+
170
+ | 检查项 | 说明 |
171
+ |--------|------|
172
+ | 网络连通性 | 服务器能否 ping 通数据库和 Redis 主机 |
173
+ | 防火墙 / 安全组 | 数据库端口(3306/5432)和 Redis 端口(6379)是否开放 |
174
+ | 用户名密码 | 确认 staging / production 环境的凭据正确 |
175
+ | 数据库存在性 | 目标数据库是否已创建 |
176
+ | 连接池配置 | HikariCP 的最大连接数是否超过数据库限制 |
177
+ | 时区 | JVM 时区、数据库时区、应用时区是否一致 |
178
+
179
+ ---
180
+
181
+ ## 常见问题
182
+
183
+ **Q: 部署后服务起不来,怎么排查?**
184
+
185
+ ```bash
186
+ # 查看服务状态
187
+ sudo systemctl status order-service --no-pager
188
+
189
+ # 查看日志
190
+ sudo journalctl -u order-service -f
191
+
192
+ # 查看应用日志
193
+ tail -f /var/log/order-service/app.log
194
+ ```
195
+
196
+ **Q: 如何回滚到上一个版本?**
197
+
198
+ ```bash
199
+ cd /opt/services/order-service
200
+ # 找到最新备份
201
+ LATEST=$(ls -t backups/*.jar | head -1)
202
+ cp "$LATEST" order-service.jar
203
+ sudo systemctl restart order-service
204
+ ```
205
+
206
+ **Q: 多个环境(staging / production)如何管理配置?**
207
+
208
+ 使用 Spring Boot profiles:
209
+ - `application-staging.yml` — 测试环境
210
+ - `application-production.yml` — 生产环境
211
+ - 打包时激活 profile:`-P staging`
212
+ - 运行时激活 profile:`--spring.profiles.active=staging`
@@ -0,0 +1,120 @@
1
+ #!/bin/bash
2
+ # ═══════════════════════════════════════════════════════════
3
+ # Java 后端部署脚本(服务器端执行)
4
+ # ═══════════════════════════════════════════════════════════
5
+ #
6
+ # 用法:
7
+ # ./deploy.sh <app-name> [profile]
8
+ #
9
+ # 示例:
10
+ # ./deploy.sh order-service staging
11
+ # ./deploy.sh order-service production
12
+ #
13
+ # 该脚本由 speccore deploy 通过 SSH 调用,也可手动在服务器上执行。
14
+ # 功能:备份旧 jar → 替换新 jar → 重启 systemd 服务 → 健康检查
15
+ # ═══════════════════════════════════════════════════════════
16
+
17
+ set -euo pipefail
18
+
19
+ APP_NAME="${1:-}"
20
+ PROFILE="${2:-staging}"
21
+
22
+ if [ -z "$APP_NAME" ]; then
23
+ echo "用法: $0 <app-name> [profile]"
24
+ echo "示例: $0 order-service staging"
25
+ exit 1
26
+ fi
27
+
28
+ DEPLOY_DIR="/opt/services/$APP_NAME"
29
+ BACKUP_DIR="$DEPLOY_DIR/backups"
30
+ LOG_DIR="/var/log/$APP_NAME"
31
+ JAR_FILE="$DEPLOY_DIR/$APP_NAME.jar"
32
+ NEW_JAR="$DEPLOY_DIR/$APP_NAME-new.jar"
33
+ HEALTH_URL="http://localhost:8080/actuator/health" # 根据实际端口和路径修改
34
+
35
+ echo "========================================"
36
+ echo "部署应用: $APP_NAME"
37
+ echo "环境: $PROFILE"
38
+ echo "========================================"
39
+
40
+ # ── 1. 预检 ──
41
+ if [ ! -f "$NEW_JAR" ]; then
42
+ echo "❌ 错误:未找到新 jar 文件: $NEW_JAR"
43
+ echo " 请确保 speccore deploy 已成功上传 jar 到该路径"
44
+ exit 1
45
+ fi
46
+
47
+ # ── 2. 创建必要目录 ──
48
+ mkdir -p "$BACKUP_DIR" "$LOG_DIR"
49
+
50
+ # ── 3. 备份旧版本 ──
51
+ if [ -f "$JAR_FILE" ]; then
52
+ BACKUP_NAME="$BACKUP_DIR/$APP_NAME-$(date +%Y%m%d-%H%M%S).jar"
53
+ cp "$JAR_FILE" "$BACKUP_NAME"
54
+ echo "✅ 旧版本已备份: $BACKUP_NAME"
55
+
56
+ # 只保留最近 5 个备份
57
+ ls -t "$BACKUP_DIR"/*.jar 2>/dev/null | tail -n +6 | xargs -r rm -f
58
+ echo "🧹 已清理旧备份(保留最近 5 个)"
59
+ else
60
+ echo "ℹ️ 首次部署,无旧版本需要备份"
61
+ fi
62
+
63
+ # ── 4. 替换 jar ──
64
+ mv "$NEW_JAR" "$JAR_FILE"
65
+ echo "✅ 已替换 jar: $JAR_FILE"
66
+
67
+ # ── 5. 确保 systemd service 文件存在 ──
68
+ SERVICE_FILE="/etc/systemd/system/$APP_NAME.service"
69
+ if [ ! -f "$SERVICE_FILE" ]; then
70
+ echo "⚠️ 警告:systemd service 文件不存在: $SERVICE_FILE"
71
+ echo " 请从 templates/deploy-java/spring-boot.service 复制并修改后部署到该路径"
72
+ echo " 然后执行: sudo systemctl daemon-reload && sudo systemctl enable $APP_NAME"
73
+ exit 1
74
+ fi
75
+
76
+ # ── 6. 重启服务 ──
77
+ echo "🔄 重启服务..."
78
+ sudo systemctl daemon-reload
79
+ sudo systemctl restart "$APP_NAME"
80
+
81
+ # ── 7. 等待启动 ──
82
+ echo "⏳ 等待服务启动(最多 30 秒)..."
83
+ for i in {1..30}; do
84
+ sleep 1
85
+ if systemctl is-active --quiet "$APP_NAME"; then
86
+ echo "✅ 服务已启动"
87
+ break
88
+ fi
89
+ if [ "$i" -eq 30 ]; then
90
+ echo "❌ 服务启动超时"
91
+ echo "📋 日志 tail -n 50:"
92
+ sudo journalctl -u "$APP_NAME" --no-pager -n 50 || true
93
+ exit 1
94
+ fi
95
+ done
96
+
97
+ # ── 8. 健康检查 ──
98
+ echo "🏥 执行健康检查..."
99
+ for i in {1..10}; do
100
+ sleep 2
101
+ if curl -sf "$HEALTH_URL" >/dev/null 2>&1; then
102
+ echo "✅ 健康检查通过: $HEALTH_URL"
103
+ break
104
+ fi
105
+ if [ "$i" -eq 10 ]; then
106
+ echo "⚠️ 健康检查未通过,但服务已启动"
107
+ echo " 请手动检查: curl $HEALTH_URL"
108
+ fi
109
+ done
110
+
111
+ # ── 9. 显示状态 ──
112
+ echo ""
113
+ echo "========================================"
114
+ echo "📋 部署完成"
115
+ echo "========================================"
116
+ sudo systemctl status "$APP_NAME" --no-pager || true
117
+ echo ""
118
+ echo "日志查看:"
119
+ echo " journalctl -u $APP_NAME -f"
120
+ echo " tail -f $LOG_DIR/app.log"
@@ -0,0 +1,35 @@
1
+ [Unit]
2
+ Description={{APP_NAME}}
3
+ After=network.target
4
+
5
+ [Service]
6
+ Type=simple
7
+ User={{DEPLOY_USER}}
8
+ Group={{DEPLOY_USER}}
9
+ WorkingDirectory={{DEPLOY_DIR}}
10
+
11
+ # Spring Boot Profile(按环境切换:staging / production / test)
12
+ Environment="SPRING_PROFILES_ACTIVE={{PROFILE}}"
13
+
14
+ # JVM 参数
15
+ Environment="JAVA_OPTS=-Xms{{JVM_XMS}} -Xmx{{JVM_XMX}} -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom"
16
+
17
+ # 启动命令
18
+ ExecStart=/usr/bin/java $JAVA_OPTS -jar {{APP_NAME}}.jar
19
+
20
+ # 优雅停止(SIGTERM 触发 Spring Boot 的 shutdown hook)
21
+ ExecStop=/bin/kill -SIGTERM $MAINPID
22
+
23
+ # 进程管理
24
+ Restart=on-failure
25
+ RestartSec=10
26
+ StartLimitInterval=60s
27
+ StartLimitBurst=3
28
+
29
+ # 日志输出(systemd 240+ 支持 append 模式)
30
+ # 旧版本 systemd 可改用:StandardOutput=file:/var/log/{{APP_NAME}}/app.log
31
+ StandardOutput=append:/var/log/{{APP_NAME}}/app.log
32
+ StandardError=append:/var/log/{{APP_NAME}}/error.log
33
+
34
+ [Install]
35
+ WantedBy=multi-user.target
@@ -0,0 +1,59 @@
1
+ # Nginx 服务器部署指南(纯服务器,非 Docker)
2
+
3
+ > 本目录提供 **ssh 类型部署**场景下前端站点的 Nginx 服务器端配置模板。
4
+ > Docker 场景(Nginx 容器托管前端)请使用 `templates/deploy-docker/nginx.conf`。
5
+
6
+ ---
7
+
8
+ ## 两种 Nginx 场景怎么选
9
+
10
+ | 场景 | 部署类型 | 配置文件 | Nginx 位置 |
11
+ |:---|:---|:---|:---|
12
+ | **纯服务器**:构建产物上传到服务器 Nginx 静态目录,后端跑进程/systemd | `ssh`(推荐)/ `sftp` | 本目录 `nginx-site.conf` | 服务器 `/etc/nginx/conf.d/` |
13
+ | **容器化**:前端打成镜像由 Nginx 容器托管 | `docker` | `deploy-docker/nginx.conf` | 镜像内 `/etc/nginx/conf.d/` |
14
+
15
+ ## 快速开始(前端 ssh 部署 + 服务器 Nginx 托管)
16
+
17
+ ```bash
18
+ # 1. 服务器端(只需一次):复制站点配置并替换占位符
19
+ sudo cp nginx-site.conf /etc/nginx/conf.d/admin-web.conf
20
+ sudo sed -i 's/{{DOMAIN}}/admin.example.com/; s|{{APP_DIR}}|/var/www/html/admin-web|; s|{{BACKEND_HOST}}|127.0.0.1:8080|' /etc/nginx/conf.d/admin-web.conf
21
+ sudo nginx -t && sudo nginx -s reload
22
+
23
+ # 2. PROJECT.yaml 配置 ssh 类型部署
24
+ # remote_dir: /var/www/html/admin-web
25
+ # script: sudo nginx -s reload
26
+
27
+ # 3. 部署(构建 → 上传 → 重载 Nginx)
28
+ speccore deploy --env staging --platform admin-web
29
+ ```
30
+
31
+ ## 模板包含内容
32
+
33
+ - SPA 路由回退(`try_files` → `/index.html`)
34
+ - gzip 压缩
35
+ - 静态资源长期缓存(`immutable`)
36
+ - `/api/` 反向代理到后端(同机 `127.0.0.1:8080` 或跨机内网地址)
37
+ - WebSocket 升级(注释备用)
38
+ - 健康检查端点透传(`/healthz` → 后端 `/actuator/health`,注释备用)
39
+ - HTTPS server 块(证书就绪后启用)
40
+ - 隐藏文件访问拦截
41
+
42
+ ## 占位符
43
+
44
+ | 占位符 | 说明 | 示例 |
45
+ |:---|:---|:---|
46
+ | `{{DOMAIN}}` | 站点域名或 IP | `admin.example.com` |
47
+ | `{{APP_DIR}}` | 静态资源目录(= `remote_dir`) | `/var/www/html/admin-web` |
48
+ | `{{BACKEND_HOST}}` | 后端地址 | `127.0.0.1:8080` |
49
+
50
+ ## 与冒烟测试联动
51
+
52
+ 部署完成后可在 `.speccore/environments/{env}.yaml` 的 `tests.base_urls` 配置站点地址,
53
+ `speccore verify` 的部署后冒烟将自动访问验证:
54
+
55
+ ```yaml
56
+ tests:
57
+ base_urls:
58
+ admin-web: https://admin.example.com
59
+ ```
@@ -0,0 +1,103 @@
1
+ # ═══════════════════════════════════════════════════════════
2
+ # Nginx 服务器站点配置模板(纯服务器部署,非 Docker 场景)
3
+ # ═══════════════════════════════════════════════════════════
4
+ #
5
+ # 适用场景:speccore deploy 的 ssh 类型部署,前端构建产物
6
+ # 上传到 Nginx 服务器静态目录,后端以进程/服务方式跑在
7
+ # 同一台(或另一台)服务器上。
8
+ #
9
+ # 用法:
10
+ # 1. 复制本文件到服务器: /etc/nginx/conf.d/<your-site>.conf
11
+ # (或 /etc/nginx/sites-available/ + sites-enabled 软链)
12
+ # 2. 替换 {{占位符}}
13
+ # 3. 校验并重载: sudo nginx -t && sudo nginx -s reload
14
+ #
15
+ # 与 PROJECT.yaml 的对应关系(ssh 类型部署):
16
+ # remote_dir → 下方 root 指向的目录
17
+ # script → sudo nginx -s reload(部署完成后重载配置)
18
+ #
19
+ # 占位符说明:
20
+ # {{DOMAIN}} 站点域名(或服务器 IP)
21
+ # {{APP_DIR}} 静态资源目录(= remote_dir,如 /var/www/html/admin-web)
22
+ # {{BACKEND_HOST}} 后端地址(同机为 127.0.0.1:8080,跨机为内网 IP:端口)
23
+ # ═══════════════════════════════════════════════════════════
24
+
25
+ # ── HTTP(开发/测试环境,或 HTTPS 前的重定向入口)──
26
+ server {
27
+ listen 80;
28
+ server_name {{DOMAIN}};
29
+
30
+ # 有证书后启用 HTTPS,取消注释并将整块 HTTP 改为重定向:
31
+ # return 301 https://$host$request_uri;
32
+
33
+ include /etc/nginx/conf.d/_site-common.conf;
34
+ }
35
+
36
+ # ── HTTPS(生产环境,证书就绪后启用)──
37
+ # server {
38
+ # listen 443 ssl http2;
39
+ # server_name {{DOMAIN}};
40
+ #
41
+ # ssl_certificate /etc/nginx/ssl/{{DOMAIN}}.pem;
42
+ # ssl_certificate_key /etc/nginx/ssl/{{DOMAIN}}.key;
43
+ # ssl_protocols TLSv1.2 TLSv1.3;
44
+ # ssl_session_cache shared:SSL:10m;
45
+ #
46
+ # include /etc/nginx/conf.d/_site-common.conf;
47
+ # }
48
+
49
+ # ── 站点公共配置(HTTP/HTTPS 共用,独立成文件避免重复)──
50
+ # 保存为 /etc/nginx/conf.d/_site-common.conf 后 include,
51
+ # 或直接展开合并进上方 server 块。
52
+
53
+ # 静态资源根目录(= PROJECT.yaml 中 ssh 类型的 remote_dir)
54
+ root {{APP_DIR}};
55
+ index index.html;
56
+
57
+ # gzip 压缩(减少传输体积)
58
+ gzip on;
59
+ gzip_min_length 1k;
60
+ gzip_comp_level 5;
61
+ gzip_types text/plain text/css application/javascript application/json image/svg+xml;
62
+
63
+ # ── 前端路由(SPA 应用)──
64
+ location / {
65
+ try_files $uri $uri/ /index.html;
66
+ }
67
+
68
+ # ── 静态资源长期缓存 ──
69
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
70
+ expires 1y;
71
+ add_header Cache-Control "public, immutable";
72
+ }
73
+
74
+ # ── API 反向代理到后端(同机后端)──
75
+ location /api/ {
76
+ proxy_pass http://{{BACKEND_HOST}}/api/;
77
+ proxy_set_header Host $host;
78
+ proxy_set_header X-Real-IP $remote_addr;
79
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
80
+ proxy_set_header X-Forwarded-Proto $scheme;
81
+ proxy_connect_timeout 10s;
82
+ proxy_read_timeout 60s;
83
+ }
84
+
85
+ # ── WebSocket 升级(后端含长连接/推送时启用)──
86
+ # location /ws {
87
+ # proxy_pass http://{{BACKEND_HOST}};
88
+ # proxy_http_version 1.1;
89
+ # proxy_set_header Upgrade $http_upgrade;
90
+ # proxy_set_header Connection "upgrade";
91
+ # proxy_read_timeout 3600s;
92
+ # }
93
+
94
+ # ── 后端健康检查端点透传(部署后验证用)──
95
+ # location = /healthz {
96
+ # proxy_pass http://{{BACKEND_HOST}}/actuator/health;
97
+ # access_log off;
98
+ # }
99
+
100
+ # ── 禁止访问隐藏文件 ──
101
+ location ~ /\. {
102
+ deny all;
103
+ }
@@ -0,0 +1,61 @@
1
+ # 通用部署脚本模板
2
+
3
+ > 本目录提供 `script` 类型部署的**开箱即用脚本实体**,覆盖 Jenkins 触发、FTP 上传、密码 SSH、Compose 编排、Python 服务五类场景。
4
+ > 对应 `templates/deploy-examples.yaml` 中 script 类型各节的注释示例。
5
+
6
+ ---
7
+
8
+ ## 脚本清单
9
+
10
+ | 脚本 | 场景 | 依赖 | 关键环境变量 |
11
+ |:---|:---|:---|:---|
12
+ | `trigger-jenkins.sh <job>` | 触发 Jenkins 构建发布 | `curl` | `JENKINS_URL` `JENKINS_USER` `JENKINS_TOKEN` |
13
+ | `deploy-ftp.sh [dir]` | 虚拟主机 FTP 上传(无 SSH 权限) | `lftp` | `FTP_USER` `FTP_PASS` `FTP_HOST` `FTP_REMOTE_DIR` |
14
+ | `deploy-password-ssh.sh [dir]` | 密码认证 SSH 部署(无密钥) | `sshpass` | `SSH_USER` `SSH_PASSWORD` `SSH_HOST` `SSH_REMOTE_DIR` |
15
+ | `deploy-compose.sh [file]` | 服务器端 Compose 编排部署 | `docker-compose` | — |
16
+ | `deploy-python.sh [dir]` | Python gunicorn + systemd 部署 | `rsync` | `DEPLOY_HOST` `DEPLOY_DIR` `SERVICE_NAME` |
17
+
18
+ ## 目录组织约定
19
+
20
+ 部署脚本按「执行位置」分三处存放,各司其职:
21
+
22
+ ```
23
+ ① 包内模板 templates/deploy-*/
24
+ ├── deploy-scripts/ ← 通用脚本实体(本目录,script 类型直接引用)
25
+ ├── deploy-docker/ ← Docker 构建素材 + 服务器端容器管理脚本(deploy-remote.sh)
26
+ ├── deploy-java/ ← Java systemd/Docker 素材 + 服务器端脚本(deploy.sh)
27
+ └── deploy-nginx/ ← 纯服务器 Nginx 站点配置
28
+ ↓(npm 安装后用户手动 cp 到工程)
29
+
30
+ ② 用户项目 .speccore/environments/scripts/(init 自动生成)
31
+ ├── deploy.sh ← 通用 script 类型骨架(TODO 待填)
32
+ ├── ecosystem.config.js ← pm2 类型
33
+ ├── k8s-deployment.yaml ← k8s 类型
34
+ ├── java-systemd.service / java-restart.sh ← ssh 类型 Java
35
+ └── values-{env}.yaml ← helm 类型(按环境生成)
36
+ ↓(speccore deploy 按 script/pm2_config/output_dir 字段引用)
37
+
38
+ ③ 端工程内 scripts/(用户自维护)
39
+ ← 端专属脚本,config.script 用 ./scripts/xxx.sh 相对路径引用
40
+ ```
41
+
42
+ > **路径解析(v8.3.296+)**:引擎对 `script` / `pm2_config` / k8s manifest / helm values 做双基准解析——先在端目录(code_path)找,回退项目根。`./scripts/xxx.sh` 与 `.speccore/environments/scripts/xxx` 两种写法都通。
43
+
44
+ ## 使用方式
45
+
46
+ ```yaml
47
+ # PROJECT.yaml(script 类型)
48
+ deploy:
49
+ staging:
50
+ type: script
51
+ build_cmd: npm run build
52
+ script: ./scripts/deploy-password-ssh.sh # 端工程内脚本(推荐)
53
+ # 或引用项目根资产:
54
+ # script: .speccore/environments/scripts/deploy.sh
55
+ ```
56
+
57
+ 敏感信息(密码/token)一律通过环境变量注入,勿写入配置文件或 git:
58
+
59
+ ```bash
60
+ SSH_USER=deployer SSH_PASSWORD=xxx SSH_HOST=server ./scripts/deploy-password-ssh.sh dist
61
+ ```
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+ # ═══════════════════════════════════════════════════════════
3
+ # Docker Compose 部署脚本(服务器端执行)
4
+ # ═══════════════════════════════════════════════════════════
5
+ # 用途:script 类型部署,服务器端统一拉取并启动前后端编排
6
+ # 用法:./deploy-compose.sh [compose-file]
7
+ # 示例:./deploy-compose.sh /opt/deploy/docker-compose.yml
8
+ # ═══════════════════════════════════════════════════════════
9
+ set -euo pipefail
10
+
11
+ COMPOSE_FILE="${1:-/opt/deploy/docker-compose.yml}"
12
+
13
+ echo "🚀 Compose 部署: $COMPOSE_FILE"
14
+ docker-compose -f "$COMPOSE_FILE" pull
15
+ docker-compose -f "$COMPOSE_FILE" up -d
16
+
17
+ echo "📋 运行状态:"
18
+ docker-compose -f "$COMPOSE_FILE" ps
19
+ echo "✅ 部署完成"
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ # ═══════════════════════════════════════════════════════════
3
+ # FTP 上传部署脚本(lftp)
4
+ # ═══════════════════════════════════════════════════════════
5
+ # 用途:script 类型部署,无 SSH 权限只有 FTP 的虚拟主机场景
6
+ # 环境变量(由用户 shell 环境注入,勿写入 git):
7
+ # FTP_USER / FTP_PASS / FTP_HOST / FTP_REMOTE_DIR
8
+ # 用法:FTP_USER=u FTP_PASS=p FTP_HOST=h ./deploy-ftp.sh [本地目录]
9
+ # ═══════════════════════════════════════════════════════════
10
+ set -euo pipefail
11
+
12
+ LOCAL_DIR="${1:-dist}"
13
+ FTP_REMOTE_DIR="${FTP_REMOTE_DIR:-/public_html}"
14
+
15
+ if [ -z "${FTP_USER:-}" ] || [ -z "${FTP_PASS:-}" ] || [ -z "${FTP_HOST:-}" ]; then
16
+ echo "❌ 缺少环境变量: FTP_USER / FTP_PASS / FTP_HOST"
17
+ exit 1
18
+ fi
19
+
20
+ echo "🚀 FTP 上传: $LOCAL_DIR → $FTP_HOST:$FTP_REMOTE_DIR"
21
+
22
+ lftp -u "$FTP_USER,$FTP_PASS" "$FTP_HOST" <<INNER_EOF
23
+ set ssl:verify-certificate no
24
+ mirror -R "$LOCAL_DIR" "$FTP_REMOTE_DIR"
25
+ bye
26
+ INNER_EOF
27
+
28
+ echo "✅ 上传完成"
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # ═══════════════════════════════════════════════════════════
3
+ # 密码认证 SSH 部署脚本(sshpass)
4
+ # ═══════════════════════════════════════════════════════════
5
+ # 用途:script 类型部署,无密钥只有密码的 SSH 场景
6
+ # 前置:安装 sshpass(macOS: brew install sshpass;Ubuntu: apt-get install sshpass)
7
+ # 环境变量(由用户 shell 环境注入,勿写入 git):
8
+ # SSH_USER / SSH_PASSWORD / SSH_HOST / SSH_REMOTE_DIR
9
+ # 用法:SSH_USER=u SSH_PASSWORD=p ./deploy-password-ssh.sh [本地目录]
10
+ # ═══════════════════════════════════════════════════════════
11
+ set -euo pipefail
12
+
13
+ LOCAL_DIR="${1:-dist}"
14
+ SSH_REMOTE_DIR="${SSH_REMOTE_DIR:-/var/www/html}"
15
+
16
+ if [ -z "${SSH_USER:-}" ] || [ -z "${SSH_PASSWORD:-}" ] || [ -z "${SSH_HOST:-}" ]; then
17
+ echo "❌ 缺少环境变量: SSH_USER / SSH_PASSWORD / SSH_HOST"
18
+ exit 1
19
+ fi
20
+
21
+ echo "🚀 SSH 上传: $LOCAL_DIR → $SSH_USER@$SSH_HOST:$SSH_REMOTE_DIR"
22
+
23
+ sshpass -p "$SSH_PASSWORD" scp -r "$LOCAL_DIR"/* "$SSH_USER@$SSH_HOST:$SSH_REMOTE_DIR/"
24
+ sshpass -p "$SSH_PASSWORD" ssh "$SSH_USER@$SSH_HOST" "sudo nginx -s reload"
25
+
26
+ echo "✅ 部署完成"