diff --git a/README.md b/README.md index aec9af8..ccd7d2a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ # DSH Runtime Release +## runtime-7.5:精简 MiSans 字重 + +本次待发布修订为 runtime-7.5,仅保留 MiSans Regular 和 Bold,从第三方 GitHub 仓库 boyan01/mi_sans_font 的固定提交下载独立 TTF 并逐个校验 SHA-256,合计约 15.73 MB,不再下载官方完整 ZIP。构建环境需要能够访问 raw.githubusercontent.com。 + ## runtime-7.4:文档工具、中文字体与 Chat Manager 修复 -本次待发布修订为 runtime-7.4:新增 Python、LibreOffice、Noto CJK 与 MiSans,并内置修复版 Chat Manager。DSH 版本仍为 0.2.0-rc.2,运行布局仍为 7,继续保留 runtime-7.3 的域名设置适配。已完成本地 AMD64 构建、19 项测试、离线启动及插件接口认证拒绝检查;ARM64 与线上面板完整删除流程尚未验收。 +runtime-7.4 修订内容:新增 Python、LibreOffice、Noto CJK 与 MiSans,并内置修复版 Chat Manager。DSH 版本仍为 0.2.0-rc.2,运行布局仍为 7,继续保留 runtime-7.3 的域名设置适配。已完成本地 AMD64 构建、19 项测试、离线启动及插件接口认证拒绝检查;ARM64 与线上面板完整删除流程尚未验收。 ## 内置修复版 Chat Manager @@ -18,7 +22,7 @@ Runtime 镜像包含 Debian Bookworm 的 Python 3、pip、venv(`python` 指向 这些依赖在镜像构建时安装;已有实例需要重建镜像并升级后才生效。 -另包含小米 MiSans 简体中文字体的 10 个静态 TTF 字重,保留 Noto CJK,不修改默认字体优先级。构建时从小米官方下载并校验固定 SHA-256,仅安装原始 TTF 文件;上游包变化会令构建失败,需审核后更新校验值。字体及声明位于 `/usr/local/share/fonts/misans`。MiSans 使用小米专有免费商用许可,并非开源字体许可;安装使用及对外分发镜像前应阅读[官方许可协议](https://hyperos.mi.com/font/zh/download/),不得单独分发或售卖字体。 +另包含小米 MiSans 简体中文字体的 Regular 和 Bold 两个静态 TTF 字重,保留 Noto CJK,不修改默认字体优先级。构建时从第三方镜像 boyan01/mi_sans_font 的固定提交 68f3ec3fee5830ce8a1d955d462fa0df401a5341 下载两个 TTF 并校验各自 SHA-256;镜像文件与当前官网 ZIP 不同,不保证为最新版本,GitHub 仓库许可不替代小米字体许可。字体及声明位于 `/usr/local/share/fonts/misans`。MiSans 使用小米专有免费商用许可,并非开源字体许可;安装使用及对外分发镜像前应阅读[官方许可协议](https://hyperos.mi.com/font/zh/download/),不得单独分发或售卖字体。 ## runtime-7.3:域名访问设置适配 @@ -32,7 +36,7 @@ Runtime 镜像包含 Debian Bookworm 的 Python 3、pip、venv(`python` 指向 ## 发布清单 -`release.json` 是发布入口:`schema_version` 为清单格式版本,`release_id` 标识一次发布,`version` 为精确 DSH 版本,`deployment_schema` 为运行布局版本,`platforms` 为支持的平台。当前待发布配置为 `runtime-7.4`、DSH `0.2.0-rc.2`、布局 7、`linux/amd64` 和 `linux/arm64`(aarch64,不含 32 位 ARM)。 +`release.json` 是发布入口:`schema_version` 为清单格式版本,`release_id` 标识一次发布,`version` 为精确 DSH 版本,`deployment_schema` 为运行布局版本,`platforms` 为支持的平台。当前待发布配置为 `runtime-7.5`、DSH `0.2.0-rc.2`、布局 7、`linux/amd64` 和 `linux/arm64`(aarch64,不含 32 位 ARM)。 ARM64 验收状态:已确认 Node/Caddy 基础镜像提供 ARM64 版本,但尚未完成 ARM64 runtime 构建及运行验收。清单声明会开放面板的对应平台构建入口,不等于兼容性证明;验收完成前不要推送发布。 diff --git a/image/MiSans-NOTICE.txt b/image/MiSans-NOTICE.txt index 17142c7..3bbc05b 100644 --- a/image/MiSans-NOTICE.txt +++ b/image/MiSans-NOTICE.txt @@ -1,6 +1,11 @@ This runtime uses MiSans fonts by Xiaomi. Official source: https://hyperos.mi.com/font/zh/download/ -Archive: https://hyperos.mi.com/font-download/MiSans.zip +Download mirror (third-party, not an official Xiaomi repository): +https://github.com/boyan01/mi_sans_font/tree/68f3ec3fee5830ce8a1d955d462fa0df401a5341/lib/fonts +Files: MiSans-Regular.ttf and MiSans-Bold.ttf +These mirrored files differ from the current official ZIP; they are not claimed +to be the latest release. The mirror repository's license does not replace the +Xiaomi font license. MiSans is subject to the MiSans Fonts Intellectual Property License Agreement published on the official download page. It is not an open-source font license. diff --git a/image/install-misans.mjs b/image/install-misans.mjs index 8630a77..f11ff55 100644 --- a/image/install-misans.mjs +++ b/image/install-misans.mjs @@ -1,33 +1,29 @@ import { createHash } from 'node:crypto'; -import { mkdtempSync, writeFileSync, rmSync, mkdirSync } from 'node:fs'; -import { tmpdir } from 'node:os'; +import { writeFileSync, mkdirSync } from 'node:fs'; import { join } from 'node:path'; import { execFileSync } from 'node:child_process'; -const url = 'https://hyperos.mi.com/font-download/MiSans.zip'; -const sha256 = 'b6aa1fc827035922612df8edf36e5609bca1c5441e25cd57572204569b7b81d9'; -const weights = ['Thin', 'ExtraLight', 'Light', 'Normal', 'Regular', 'Medium', 'Demibold', 'Semibold', 'Bold', 'Heavy']; +// Third-party mirror, pinned to a reviewed commit; Xiaomi's font license applies. +const base = 'https://raw.githubusercontent.com/boyan01/mi_sans_font/68f3ec3fee5830ce8a1d955d462fa0df401a5341/lib/fonts/'; +const fonts = [ + ['MiSans-Regular.ttf', '7172aa1b5c703780ee12df3fe4c50481dde01f3b125a045a398000a88d032ae5', 'Regular'], + ['MiSans-Bold.ttf', '250fb5c8d4657f103e332b0b948a995e45f2c159beb8d0528424e2d32ae421be', 'Bold'], +]; const destination = '/usr/local/share/fonts/misans'; -const temporary = mkdtempSync(join(tmpdir(), 'misans-')); -try { - const response = await fetch(url, { signal: AbortSignal.timeout(300000) }); - if (!response.ok) throw new Error(`MiSans download failed: ${response.status}`); - const archive = Buffer.from(await response.arrayBuffer()); - if (createHash('sha256').update(archive).digest('hex') !== sha256) { - throw new Error('MiSans archive checksum mismatch; review upstream changes before updating'); +mkdirSync(destination, { recursive: true }); +for (const [name, sha256] of fonts) { + console.log('Downloading ' + name); + const response = await fetch(base + name, { signal: AbortSignal.timeout(120000) }); + if (!response.ok) throw new Error('MiSans download failed: ' + name + ' HTTP ' + response.status); + const font = Buffer.from(await response.arrayBuffer()); + if (createHash('sha256').update(font).digest('hex') !== sha256) { + throw new Error('MiSans checksum mismatch: ' + name); } - const archivePath = join(temporary, 'MiSans.zip'); - writeFileSync(archivePath, archive); - mkdirSync(destination, { recursive: true }); - for (const weight of weights) { - const name = `MiSans-${weight}.ttf`; - // Extract only fixed, reviewed filenames; never unpack arbitrary archive paths. - const font = execFileSync('python3', ['-c', 'import sys, zipfile; sys.stdout.buffer.write(zipfile.ZipFile(sys.argv[1]).read(sys.argv[2]))', archivePath, `MiSans/ttf/${name}`], { maxBuffer: 16000000 }); - writeFileSync(join(destination, name), font, { mode: 0o644 }); - } - execFileSync('fc-cache', ['-f', destination], { stdio: 'inherit' }); - const family = execFileSync('fc-match', ['-f', '%{family}', 'MiSans'], { encoding: 'utf8' }); - if (!family.split(',').includes('MiSans')) throw new Error(`MiSans font lookup failed: ${family}`); -} finally { - rmSync(temporary, { recursive: true, force: true }); + writeFileSync(join(destination, name), font, { mode: 0o644 }); } +execFileSync('fc-cache', ['-f', destination], { stdio: 'inherit' }); +for (const [name, , style] of fonts) { + const file = execFileSync('fc-match', ['-f', '%{file}', 'MiSans:style=' + style], { encoding: 'utf8' }); + if (file !== join(destination, name)) throw new Error('MiSans font lookup failed: ' + style + ': ' + file); +} +console.log('Installed MiSans Regular and Bold (SHA-256 verified)'); diff --git a/release.json b/release.json index 2ba2302..1c70953 100644 --- a/release.json +++ b/release.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "release_id": "runtime-7.4", + "release_id": "runtime-7.5", "version": "0.2.0-rc.2", "deployment_schema": 7, "platforms": ["linux/amd64", "linux/arm64"]