diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 063ddad..28c2840 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,3 +50,22 @@ jobs: run: ./build.sh - name: Verify architectures, deployment target and resources run: bash .github/scripts/verify-mac-build.sh + + mac-native-tests: + name: Mac native tests + runs-on: macos-15 + timeout-minutes: 30 + env: + DEVELOPER_DIR: /Applications/Xcode_26.3.app/Contents/Developer + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: '22' + - run: npm ci --ignore-scripts + - name: Core and native tests + run: npm test + - name: Native UI tests + run: node --test tests/mac-localization-ui.js diff --git a/tests/localizations.test.js b/tests/localizations.test.js index 63085fd..8e77023 100644 --- a/tests/localizations.test.js +++ b/tests/localizations.test.js @@ -124,7 +124,8 @@ test('同一打包器发现新增成对资源、拒绝缺项和变量变更, test('原生在隔离的三语言 fixture 中读取、格式化、匹配地区与偏好', { skip: process.platform !== 'darwin' }, async () => { const { stdout: disk } = await run('/bin/df', ['-k', '/System/Volumes/Data']); const availableKiB = Number(disk.trim().split('\n').at(-1).trim().split(/\s+/)[3]); - assert.ok(availableKiB >= 80 * 1024 * 1024, '80 GiB required before compiling native harness'); + // Protects contributors' disks; hosted CI runners are disposable and smaller. + if (!process.env.CI) assert.ok(availableKiB >= 80 * 1024 * 1024, '80 GiB required before compiling native harness'); const directory = temporary('localization-native-'); try { const cases = path.join(directory, 'cases'); diff --git a/tests/mac-localization-ui.js b/tests/mac-localization-ui.js index 75e1b12..492bb21 100644 --- a/tests/mac-localization-ui.js +++ b/tests/mac-localization-ui.js @@ -25,7 +25,8 @@ async function createSyntheticImages(directory) { test('Mac WK/AppKit 本地化界面保持任务与输出,隔离偏好和剪贴板', { skip: process.platform !== 'darwin' }, async () => { const { stdout: disk } = await run('/bin/df', ['-k', '/System/Volumes/Data']); - assert.ok(Number(disk.trim().split('\n').at(-1).trim().split(/\s+/)[3]) >= 80 * 1024 * 1024, '80 GiB required before native UI build'); + // Protects contributors' disks; hosted CI runners are disposable and smaller. + if (!process.env.CI) assert.ok(Number(disk.trim().split('\n').at(-1).trim().split(/\s+/)[3]) >= 80 * 1024 * 1024, '80 GiB required before native UI build'); const temporaryRoot = path.join(root, '.derivedData'); fs.mkdirSync(temporaryRoot, { recursive: true }); const directory = fs.mkdtempSync(path.join(temporaryRoot, 'localization-ui-')); diff --git a/tests/mac-settings-window.test.js b/tests/mac-settings-window.test.js index 7d0b1d9..354ea53 100644 --- a/tests/mac-settings-window.test.js +++ b/tests/mac-settings-window.test.js @@ -11,7 +11,8 @@ const root = path.resolve(__dirname, '..'); test('设置窗口居中在主窗口上,并完整显示在屏幕可见区域内', { skip: process.platform !== 'darwin' }, async () => { const { stdout: disk } = await run('/bin/df', ['-k', '/System/Volumes/Data']); const availableKiB = Number(disk.trim().split('\n').at(-1).trim().split(/\s+/)[3]); - assert.ok(availableKiB >= 80 * 1024 * 1024, '80 GiB required before compiling native harness'); + // Protects contributors' disks; hosted CI runners are disposable and smaller. + if (!process.env.CI) assert.ok(availableKiB >= 80 * 1024 * 1024, '80 GiB required before compiling native harness'); const buildRoot = path.join(root, '.derivedData', 'settings-window-tests'); fs.mkdirSync(buildRoot, { recursive: true }); const directory = fs.mkdtempSync(path.join(buildRoot, 'settings-window-')); diff --git "a/\350\264\241\347\214\256\346\214\207\345\215\227.md" "b/\350\264\241\347\214\256\346\214\207\345\215\227.md" index 3084b52..8ebdf21 100644 --- "a/\350\264\241\347\214\256\346\214\207\345\215\227.md" +++ "b/\350\264\241\347\214\256\346\214\207\345\215\227.md" @@ -8,7 +8,7 @@ - 核心测试需要 Node.js 22:运行 `npm ci --ignore-scripts`,再运行 `npm test`。 - Mac App 通用构建需要安装 Xcode 的 Mac:运行 `./build.sh`,再运行 `bash .github/scripts/verify-mac-build.sh` 核验产物。构建为未签名的本地 App,不需要 Apple 签名证书,也不会分发 App。 -- Mac 本地界面测试可单独运行 `node --test tests/mac-localization-ui.js`。它会打开隔离的测试窗口,使用合成图片、独立偏好和剪贴板替身;不属于默认 `npm test` 或 CI 检查。 +- Mac 本地界面测试可单独运行 `node --test tests/mac-localization-ui.js`。它会打开隔离的测试窗口,使用合成图片、独立偏好和剪贴板替身;不属于默认 `npm test`,由 CI 的 `Mac native tests` 在 macOS 上运行。在 macOS 上运行 `npm test` 也会编译原生测试并短暂打开测试窗口。 GitHub Actions 会在所有目标分支的 Pull Request、推送到 `main` 和手动触发时运行两项检查:Ubuntu 24.04 上使用 Node.js 22 运行核心测试(跳过 Mac 原生测试);macOS 15 上使用 Xcode 26.3 运行构建与产物核验,检查面向 macOS 13 及以上版本的 arm64 与 x86_64 通用构建及其成对语言资源。 @@ -22,7 +22,7 @@ Run the checks relevant to your change when practical: - Core tests require Node.js 22: run `npm ci --ignore-scripts`, then `npm test`. - The universal Mac app build requires a Mac with Xcode: run `./build.sh`, then `bash .github/scripts/verify-mac-build.sh` to verify the result. It creates an unsigned local app; no Apple signing certificate is needed, and the app is not distributed. -- Run local Mac UI tests separately with `node --test tests/mac-localization-ui.js`. They open an isolated test window and use synthetic images, separate preferences, and an intercepted clipboard. They are excluded from the default `npm test` and CI checks. +- Run local Mac UI tests separately with `node --test tests/mac-localization-ui.js`. They open an isolated test window and use synthetic images, separate preferences, and an intercepted clipboard. They are excluded from the default `npm test`; the `Mac native tests` CI check runs them on macOS. On macOS, `npm test` also compiles the native tests and briefly opens test windows. GitHub Actions runs two checks for pull requests targeting any branch, pushes to `main`, and manual dispatches: core tests on Ubuntu 24.04 with Node.js 22 (skipping Mac native tests), and a build and artifact verification on macOS 15 with Xcode 26.3 to check the arm64 and x86_64 universal build for macOS 13 or later and its paired localization resources.