diff --git a/README.md b/README.md index 9ca66d2..01371ef 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,37 @@ ## 发布清单 -`release.json` 是发布入口:`schema_version` 为清单格式版本,`release_id` 标识一次发布,`version` 为精确 DSH 版本,`deployment_schema` 为运行布局版本,`platforms` 为支持的平台。当前为 `runtime-7.1`、DSH `0.2.0-rc.2`、布局 7、`linux/amd64`。 +`release.json` 是发布入口:`schema_version` 为清单格式版本,`release_id` 标识一次发布,`version` 为精确 DSH 版本,`deployment_schema` 为运行布局版本,`platforms` 为支持的平台。当前待发布配置为 `runtime-7.2`、DSH `0.2.0-rc.2`、布局 7、`linux/amd64` 和 `linux/arm64`(aarch64,不含 32 位 ARM)。 + +ARM64 验收状态:已确认 Node/Caddy 基础镜像提供 ARM64 版本,但尚未完成 ARM64 runtime 构建及运行验收。清单声明会开放面板的对应平台构建入口,不等于兼容性证明;验收完成前不要推送发布。 此分支是可信代码来源,不是仅供读取的数据源:Dockerfile 和安装脚本会在构建时执行。只使用经过审核的提交,不要将不可信分支、PR 或任意远端内容直接用于构建。清单本身不代表镜像已经完成运行验收。 ## 本地构建与检查 -需要 Docker、Node.js,以及拉取基础镜像和构建依赖的网络。从仓库根目录执行,版本和平台直接取自清单,不跟踪 latest: +需要 Docker、Node.js,以及拉取基础镜像和构建依赖的网络。从仓库根目录执行,DSH 版本取自清单,平台按 Docker daemon 架构选择,不跟踪 latest: ~~~sh +set -eu DSH_VERSION="$(node -p "require('./release.json').version")" -PLATFORM="$(node -p "require('./release.json').platforms[0]")" +case "$(docker info --format '{{.Architecture}}')" in + aarch64|arm64) PLATFORM=linux/arm64 ;; + x86_64|amd64) PLATFORM=linux/amd64 ;; + *) echo 'Unsupported Docker daemon architecture' >&2; exit 1 ;; +esac RELEASE_ID="$(node -p "require('./release.json').release_id")" node --test image/*.test.mjs docker build --platform "$PLATFORM" \ --build-arg DSH_VERSION="$DSH_VERSION" \ - -t "dsh-web:$RELEASE_ID" ./image + -t "dsh-web:$RELEASE_ID-${PLATFORM#linux/}" ./image ~~~ +默认按 Docker daemon 架构原生构建,不再固定取清单第一个平台。在交叉构建环境可手动将 PLATFORM 设置为 linux/arm64 或 linux/amd64;需要事先配置对应原生 builder 或 QEMU/binfmt,仅设置 --platform 不会自动提供模拟能力。 + +Dockerfile 两个阶段均继承目标平台,无需写死架构;不要将 Caddy 阶段固定为构建主机平台,也不要复用另一架构的 node_modules。 + +发布前分别验证两个架构的镜像构建、非 root 启动、代理认证、终端及原生模块、内置插件离线协调、工作区写入和重启持久化,以及升级/恢复路径。迁移工作区时需重新安装其中的架构相关依赖。 + `image/` 是构建上下文。构建只生成本地镜像,不推送镜像,也不自动发布分支。保留 `image/init-profile.test.mjs` 作为独立 runtime 回归测试,覆盖初始化幂等性、保留已有配置和拒绝符号链接目录;它不依赖面板,且被 `image/.dockerignore` 排除在构建上下文之外。此测试不能替代真实容器启动、插件和持久化验收。 ## 布局 7 合约 diff --git a/image/platforms.test.mjs b/image/platforms.test.mjs new file mode 100644 index 0000000..377fbd8 --- /dev/null +++ b/image/platforms.test.mjs @@ -0,0 +1,16 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; + +test('release targets AMD64 and ARM64 with layout 7', () => { + const release = JSON.parse(readFileSync(new URL('../release.json', import.meta.url), 'utf8')); + assert.deepEqual(release.platforms, ['linux/amd64', 'linux/arm64']); + assert.equal(release.deployment_schema, 7); +}); + +test('Node and Caddy stages inherit the target platform', () => { + const dockerfile = readFileSync(new URL('./Dockerfile', import.meta.url), 'utf8'); + const stages = dockerfile.split(String.fromCharCode(10)).filter(line => line.startsWith('FROM ')); + assert.deepEqual(stages, ['FROM caddy:2.10.2 AS proxy', 'FROM node:24-bookworm-slim']); + assert.ok(dockerfile.includes('COPY --from=proxy /usr/bin/caddy /usr/bin/caddy')); +}); diff --git a/release.json b/release.json index ef73d9b..abf6384 100644 --- a/release.json +++ b/release.json @@ -1,7 +1,7 @@ { "schema_version": 1, - "release_id": "runtime-7.1", + "release_id": "runtime-7.2", "version": "0.2.0-rc.2", "deployment_schema": 7, - "platforms": ["linux/amd64"] + "platforms": ["linux/amd64", "linux/arm64"] }