@wdyy/skills 0.1.8 → 0.1.10
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/.well-known/skills/wdyy-deployment-standard/SKILL.md +1 -0
- package/.well-known/skills/wdyy-deployment-standard/reference/linux-deployment-rules.md +3 -3
- package/.well-known/skills/wdyy-deployment-standard/scripts/validate-deployment-package.mjs +0 -3
- package/.well-known/skills/wdyy-deployment-standard/scripts/validate-deployment-package.test.mjs +5 -6
- package/.well-known/skills/wdyy-deployment-standard/templates/deploy.sh.template +0 -4
- package/.well-known/skills/wdyy-deployment-standard/templates/env.example.template +2 -2
- package/README.md +1 -1
- package/package.json +1 -1
|
@@ -25,6 +25,7 @@ description: 基于标准五段根 .env,为无 CI/CD 的多项目 Linux 服务
|
|
|
25
25
|
- 宿主机 Nginx 只监听根 `.env` 的 `PROJECT_HTTP_PORT`,`/api/` 代理活动后端,其他请求代理活动前端。
|
|
26
26
|
- 所有容器只把项目根 `./logs` 挂载到 `/app/logs`;日志文件直接位于 `logs/`,不得创建服务、颜色或日期子目录。
|
|
27
27
|
- 根 `.env` 原样复制到 `deploy/.env` 并人工上传,但必须被 `.dockerignore` 排除,且不得进入版本目录或任一镜像。
|
|
28
|
+
- `FRONTEND_BASE_IMAGE` 与 `BACKEND_BASE_IMAGE` 使用非空 Docker 镜像引用;可直接使用本地带标签镜像。相同标签在不同时间重新构建时可能对应不同基础镜像内容,但已导出的项目成品镜像仍按版本确定部署。
|
|
28
29
|
- 环境文件固定按“前端、后端、数据库、API、部署”排列;部署生成器保留前四段和已有值,只扩充部署段。
|
|
29
30
|
- `DATABASE_MIGRATION_MODE=manual` 时只打包迁移与执行脚本;`none` 时不要求数据库文件。任何部署命令都不得自动访问数据库。
|
|
30
31
|
- 相同输入生成的 deploy.sh、Compose、Nginx 配置必须字节一致;版本指针、镜像归档和 manifest 可随发布变化。
|
|
@@ -40,14 +40,14 @@ FRONTEND_BLUE_PORT=19091
|
|
|
40
40
|
FRONTEND_GREEN_PORT=19092
|
|
41
41
|
BACKEND_BLUE_PORT=19093
|
|
42
42
|
BACKEND_GREEN_PORT=19094
|
|
43
|
-
FRONTEND_BASE_IMAGE=nginx:
|
|
44
|
-
BACKEND_BASE_IMAGE=node:24-
|
|
43
|
+
FRONTEND_BASE_IMAGE=nginx:stable
|
|
44
|
+
BACKEND_BASE_IMAGE=node:24-alpine3.24
|
|
45
45
|
DATABASE_MIGRATION_MODE=none
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
`FRONTEND_URL`、`FRONTEND_PORT`、`BACKEND_URL`、`BACKEND_PORT` 是应用监听的唯一来源;容器、蓝绿和项目入口的健康/版本 URL 必须由对应主机、端口与固定路径确定性构造。不得增加 `FRONTEND_CONTAINER_PORT`、`BACKEND_CONTAINER_PORT`、`BACKEND_LISTEN_HOST`、`*_HEALTH_URL` 或 `*_VERSION_URL`。通配监听地址 `0.0.0.0` 仅在主动本机探测时转换为 `127.0.0.1`。
|
|
49
49
|
|
|
50
|
-
部署示例值只说明字段,生成目标项目后必须由工程师确认 `.env` 实际值,不得保留占位符或示例部署端口。`PROJECT_NAME` 只允许 `^[a-z][a-z0-9_]*$`。所有宿主机端口必须互不相同且在 1–65535
|
|
50
|
+
部署示例值只说明字段,生成目标项目后必须由工程师确认 `.env` 实际值,不得保留占位符或示例部署端口。`PROJECT_NAME` 只允许 `^[a-z][a-z0-9_]*$`。所有宿主机端口必须互不相同且在 1–65535;两个基础镜像必须是非空 Docker 镜像引用,可使用本地带标签镜像。相同标签在不同时间重新构建时可能解析为不同基础镜像内容;成功构建后导出的项目成品镜像仍用于服务器端确定部署。数据库连接键允许为空,但项目使用数据库时必须填写真实值。
|
|
51
51
|
|
|
52
52
|
`.env` 权限必须为 `0600` 或只读的 `0400`。部署脚本只把明确的部署键载入自身环境;数据库密码、JWT 等其他应用键保留在文件中供 Compose 注入容器,不得改变脚本的 `PATH`、Shell 选项或命令行为。
|
|
53
53
|
|
|
@@ -129,9 +129,6 @@ if (!/^\/.+[^/]$/.test(env.get('SERVER_PROJECTS_ROOT'))) throw new Error('Invali
|
|
|
129
129
|
for (const key of ['FRONTEND_URL', 'BACKEND_URL', 'DOCKER_BIND_IP']) {
|
|
130
130
|
if (!/^[A-Za-z0-9:.%-]+$/.test(env.get(key))) throw new Error(`${key} contains unsafe characters`);
|
|
131
131
|
}
|
|
132
|
-
for (const key of ['FRONTEND_BASE_IMAGE', 'BACKEND_BASE_IMAGE']) {
|
|
133
|
-
if (!/@sha256:[0-9a-f]{64}$/.test(env.get(key))) throw new Error(`${key} must be pinned by digest`);
|
|
134
|
-
}
|
|
135
132
|
const migrationMode = env.get('DATABASE_MIGRATION_MODE');
|
|
136
133
|
if (!['manual', 'none'].includes(migrationMode)) throw new Error('DATABASE_MIGRATION_MODE must be manual or none');
|
|
137
134
|
if (env.has('LOG_DIR') || env.has('HOST_LOG_DIR')) throw new Error('Root .env must not configure log directories');
|
package/.well-known/skills/wdyy-deployment-standard/scripts/validate-deployment-package.test.mjs
CHANGED
|
@@ -60,8 +60,8 @@ FRONTEND_BLUE_PORT=19091
|
|
|
60
60
|
FRONTEND_GREEN_PORT=19092
|
|
61
61
|
BACKEND_BLUE_PORT=19093
|
|
62
62
|
BACKEND_GREEN_PORT=19094
|
|
63
|
-
FRONTEND_BASE_IMAGE=nginx
|
|
64
|
-
BACKEND_BASE_IMAGE=node
|
|
63
|
+
FRONTEND_BASE_IMAGE=nginx:stable
|
|
64
|
+
BACKEND_BASE_IMAGE=node:24-alpine3.24
|
|
65
65
|
DATABASE_MIGRATION_MODE=${mode}
|
|
66
66
|
${extra}`;
|
|
67
67
|
}
|
|
@@ -319,12 +319,11 @@ test('dotenv 被作为数据解析,不执行命令替换或覆盖脚本 PATH',
|
|
|
319
319
|
await assert.rejects(access(join(fixture.root, 'should-not-exist')));
|
|
320
320
|
});
|
|
321
321
|
|
|
322
|
-
test('build
|
|
322
|
+
test('build 接受带标签基础镜像并拒绝重复键和额外版本参数', async () => {
|
|
323
323
|
const duplicate = await createFixture({ extraEnv: 'PROJECT_NAME=duplicate\n' });
|
|
324
324
|
assert.notEqual(runBuild(duplicate).status, 0);
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
assert.notEqual(runBuild(mutable).status, 0);
|
|
325
|
+
const tagged = await createFixture();
|
|
326
|
+
assert.equal(runBuild(tagged).status, 0);
|
|
328
327
|
const extra = await createFixture();
|
|
329
328
|
assert.equal(runBuild(extra, {}, '20260808-001').status, 2);
|
|
330
329
|
const logDirectory = await createFixture({ extraEnv: 'LOG_DIR=/tmp/logs\n' });
|
|
@@ -132,10 +132,6 @@ validate_configuration() {
|
|
|
132
132
|
[[ "$seen" != *" $port "* ]] || fail "host ports must be unique; duplicate value: $port"
|
|
133
133
|
seen+="$port "
|
|
134
134
|
done
|
|
135
|
-
[[ "$FRONTEND_BASE_IMAGE" =~ @sha256:[0-9a-f]{64}$ ]] ||
|
|
136
|
-
fail "FRONTEND_BASE_IMAGE must be pinned by sha256 digest"
|
|
137
|
-
[[ "$BACKEND_BASE_IMAGE" =~ @sha256:[0-9a-f]{64}$ ]] ||
|
|
138
|
-
fail "BACKEND_BASE_IMAGE must be pinned by sha256 digest"
|
|
139
135
|
[[ "$DATABASE_MIGRATION_MODE" == manual || "$DATABASE_MIGRATION_MODE" == none ]] ||
|
|
140
136
|
fail "DATABASE_MIGRATION_MODE must be manual or none"
|
|
141
137
|
}
|
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ wdyy update-skill --all
|
|
|
64
64
|
|
|
65
65
|
### 使用发布脚本
|
|
66
66
|
|
|
67
|
-
推荐从项目根目录手动运行 `release_npm.sh
|
|
67
|
+
推荐从项目根目录手动运行 `release_npm.sh`。脚本会检查工作区、组织权限、lint 与打包内容,自动执行 `npm version <patch|minor|major>`、`npm publish --access public`;发布成功后等待 5 秒,再一次查询刚发布的确切版本进行 registry 核验。它不会执行登录、浏览器认证或处理认证凭据。
|
|
68
68
|
|
|
69
69
|
首次运行或登录失效时,先手工登录;脚本检测到未登录也会提示并退出:
|
|
70
70
|
|