diff --git a/.github/workflows/linux-lua.yml b/.github/workflows/linux-lua.yml index 6c7ac89..f7f477b 100644 --- a/.github/workflows/linux-lua.yml +++ b/.github/workflows/linux-lua.yml @@ -34,6 +34,8 @@ jobs: env: PYTHONUTF8: "1" CARGO_TERM_COLOR: always + RUST_BACKTRACE: "1" + RUST_TOOLCHAIN: "1.97.1" steps: - uses: actions/checkout@v4 with: @@ -61,22 +63,12 @@ jobs: with: toolchain: "1.97.1" - uses: Swatinem/rust-cache@v2 - - name: Test native titlebar alignment - if: runner.os == 'macOS' - run: >- - cargo test --locked -p nebula --bin pebrel --features gpui-test-support platform::window_chrome::macos::tests:: - - name: Test all Python helpers - if: ${{ !cancelled() }} - run: python -m unittest discover -s scripts/tests -v - - name: Test all conformance harness helpers - if: ${{ !cancelled() }} - run: python -m unittest discover -s scripts/conformance/tests -v - - name: Test the full Rust workspace - if: ${{ !cancelled() }} - run: cargo test --locked --workspace - - name: Test all GPUI product and interaction cases - if: ${{ !cancelled() }} - run: cargo test --locked -p nebula --bin pebrel --features gpui-test-support + with: + shared-key: ${{ runner.os == 'Windows' && 'windows' || runner.os == 'Linux' && 'linux' || 'macos' }} + cache-workspace-crates: true + cache-on-failure: true + - name: Test complete workspace and native harness + run: python scripts/ci_native_tests.py - name: Check source architecture if: ${{ !cancelled() && runner.os == 'Linux' }} run: python scripts/check_architecture.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fddf61c..4d89fb2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -106,6 +106,7 @@ jobs: python3 scripts/check_platform_cfg.py python3 -m unittest \ scripts.tests.test_stable_release \ + scripts.tests.test_ci_native_tests \ scripts.tests.test_preview_release \ scripts.tests.test_macos_dmg \ scripts.tests.test_ai_session_probe \ @@ -118,6 +119,66 @@ jobs: bash -n scripts/package-linux.sh scripts/package-macos.sh python3 -m py_compile scripts/stable_release.py scripts/preview_release.py + native-tests: + name: Native tests (${{ matrix.platform }}) + if: ${{ !inputs.windows_only }} + needs: prepare + timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-22.04 + platform: linux-x64 + cache: linux + - runner: windows-2022 + platform: windows-x64 + cache: windows + - runner: macos-26 + platform: macos-arm64 + cache: macos + - runner: macos-26-intel + platform: macos-x64 + cache: macos + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: Install native test dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential cmake pkg-config zsh libasound2-dev libdbus-1-dev libudev-dev \ + libfontconfig1-dev libfreetype6-dev libegl1-mesa-dev libgl1-mesa-dev \ + libwayland-dev libxkbcommon-dev libxkbcommon-x11-dev libx11-xcb-dev \ + libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \ + libxcb-xinput-dev libxcb-xkb-dev libxi-dev + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + - uses: Swatinem/rust-cache@v2 + with: + shared-key: ${{ matrix.cache }} + cache-workspace-crates: true + cache-on-failure: true + - name: Prepare pinned Windows console runtime + if: runner.os == 'Windows' + shell: pwsh + run: ./scripts/prepare-windows-runtime.ps1 -Destination assets/windows/conhost + - name: Test complete workspace and native harness + run: python scripts/ci_native_tests.py + - name: Upload native compilation timings + if: always() + uses: actions/upload-artifact@v4 + with: + name: native-timings-${{ matrix.platform }} + path: target/cargo-timings + if-no-files-found: warn + retention-days: 14 + linux: name: Linux x86_64 stable package if: ${{ !inputs.windows_only }} @@ -151,15 +212,9 @@ jobs: - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true - - name: Test workspace and startup contracts - run: | - cargo test --locked --workspace - cargo test --locked -p nebula --bin pebrel --features gpui-shell - python3 -m unittest scripts.tests.test_shell_integration - cargo test --locked -p nebula --features gpui-test-support dialog - cargo test --locked -p nebula --bin pebrel --features gpui-test-support gpui_shell:: + cache-workspace-crates: true - name: Build GPUI release binary - run: cargo build --locked --release -p nebula --bin pebrel --features gpui-shell + run: cargo build --locked --release -p nebula --bin pebrel --features gpui-shell --timings - name: Download pinned linuxdeploy env: LINUXDEPLOY: ${{ runner.temp }}/linuxdeploy-x86_64.AppImage @@ -284,15 +339,9 @@ jobs: - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true - - name: Test workspace and native startup contracts - run: | - cargo test --locked --workspace - cargo test --locked -p nebula --bin pebrel --features gpui-shell - python3 -m unittest scripts.tests.test_shell_integration scripts.conformance.tests.test_posix_lifecycle - cargo test --locked -p nebula --features gpui-test-support dialog - cargo test --locked -p nebula --bin pebrel --features gpui-test-support gpui_shell:: + cache-workspace-crates: true - name: Build GPUI release binary - run: cargo build --locked --release -p nebula --bin pebrel --features gpui-shell + run: cargo build --locked --release -p nebula --bin pebrel --features gpui-shell --timings - name: Import Developer ID signing credentials if: ${{ env.MACOS_SIGNING == 'developer-id' }} env: @@ -422,9 +471,9 @@ jobs: $run = Invoke-RestMethod -Uri "https://api.github.com/repos/$env:GITHUB_REPOSITORY/actions/runs/$env:VALIDATED_RUN" -Headers $headers -ErrorAction Stop if ($run.head_sha -ne $env:SELECTED_COMMIT) { throw 'Validated run source differs.' } $jobs = Invoke-RestMethod -Uri "https://api.github.com/repos/$env:GITHUB_REPOSITORY/actions/runs/$env:VALIDATED_RUN/jobs?per_page=100" -Headers $headers -ErrorAction Stop - $windows = @($jobs.jobs | Where-Object name -eq 'Windows x64 stable package') - $tests = @($windows.steps | Where-Object { $_.name -eq 'Test workspace and native harness' -and $_.conclusion -eq 'success' }) - if ($windows.Count -ne 1 -or $tests.Count -ne 1) { throw 'Prior Windows native tests did not pass.' } + $windows = @($jobs.jobs | Where-Object { $_.name -in @('Windows x64 stable package', 'Native tests (windows-x64)') }) + $tests = @($windows.steps | Where-Object { $_.name -in @('Test workspace and native harness', 'Test complete workspace and native harness') -and $_.conclusion -eq 'success' }) + if ($tests.Count -ne 1) { throw 'Prior Windows native tests did not pass.' } - uses: actions/checkout@v4 if: ${{ inputs.source_commit != '' }} with: @@ -438,32 +487,18 @@ jobs: - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true + cache-workspace-crates: true - name: Prepare pinned Windows console runtime shell: pwsh run: | & "$env:RUNNER_TEMP/prepare-windows-runtime.ps1" -Destination assets/windows/conhost & "$env:RUNNER_TEMP/runtime-tests/windows-runtime.tests.ps1" -ArchivePath (Join-Path ([IO.Path]::GetTempPath()) 'pebrel-conpty-source-v1.5.0.zip') - name: Test workspace and native harness - if: ${{ inputs.source_commit == '' }} - shell: pwsh - run: | - python -m unittest scripts.conformance.tests.test_lifecycle scripts.conformance.tests.test_scrollback - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - cargo test --locked --workspace - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - cargo test --locked -p nebula --bin pebrel --features gpui-shell - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - cargo test --locked -p nebula --features gpui-test-support dialog - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - cargo test --locked -p nebula --bin pebrel --features gpui-test-support gpui_shell:: - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + if: ${{ inputs.windows_only && inputs.source_commit == '' }} + run: python scripts/ci_native_tests.py - name: Build GPUI release binary shell: pwsh - run: | - cargo build --locked --release -p nebula_hook --bin pebrel-hook - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - cargo build --locked --release -p nebula --bin pebrel --features gpui-shell - exit $LASTEXITCODE + run: ./scripts/build-windows-product.ps1 -Configuration release -TargetDirectory target - name: Retain built Windows runtime before packaging uses: actions/upload-artifact@v4 with: @@ -519,7 +554,7 @@ jobs: aggregate: name: Verify stable assets and upload complete set if: ${{ !inputs.windows_only }} - needs: [prepare, linux, macos, windows] + needs: [prepare, native-tests, linux, macos, windows] runs-on: ubuntu-22.04 env: PACKAGE_VERSION: ${{ needs.prepare.outputs.version }} diff --git a/CHANGELOG.md b/CHANGELOG.md index a7cad15..499770b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Every release entry is provided in English and Simplified Chinese. 每个版本条目均同时提供英文和简体中文说明。 -## Unreleased / 未发布 +## 1.8.0 - 2026-09-14 ### English @@ -20,29 +20,68 @@ Every release entry is provided in English and Simplified Chinese. - Fixed Windows terminal focus consuming `Alt+F4` and `Alt+Space`. `Alt+F4` now uses the normal window-close flow, and `Alt+Space`, followed by `N`, uses the system menu to minimize the window. - Fixed the top Settings tab disappearing when switching to another tab. It now remains available until explicitly closed, including when tabs overflow or the tab layout changes. - Fixed `Alt+1–9` and `Ctrl+1–9` tab shortcuts losing priority to terminal input. They now work while a terminal or CLI has focus and respect custom shortcut changes without restarting. +- Fixed WSL filename search failing when the directory path contains spaces or shell punctuation. Cancelling a search stops its own directory scan. +- Aligned macOS native window controls with the sidebar and Settings buttons, and preserved their reserved space in the top tab layout. Window controls follow the system appearance. Contributed by [@WilliamWang1721](https://github.com/WilliamWang1721) in [#114](https://github.com/Kuddev/pebrel/pull/114). +- Fixed the Git drawer retaining Chinese labels when the application resolves to English. Controls, history timestamps and application notices follow the selected language; switching languages preserves the commit draft and text selection. Contributed by [@gao-jian-bin](https://github.com/gao-jian-bin) in [#118](https://github.com/Kuddev/pebrel/pull/118). +- Fixed explicitly configured terminal selection text colors being ignored. Themes without their own selection foreground preserve that setting; themes with an explicit foreground retain their precedence. Contributed by [@Aschenbath](https://github.com/Aschenbath) in [#125](https://github.com/Kuddev/pebrel/pull/125). #### Improved +- Reduced file browsing and filename-search memory use by starting recursive searches only when a query is entered, reusing a bounded cache and streaming paths beyond that cache. Repeated panel use releases obsolete results and cancels superseded searches. Case, whole-word and regular-expression options remain available, with visible feedback for incomplete searches and errors. +- Reduced background-image memory use with bounded image loading and reuse while resizing the window. Replacing an image releases the previous resources; extended backgrounds retain their fit, alignment and text readability. - Replaced the low-resolution Claude Code icon with artwork exported from SVG at 1024 pixels, and prepared Agent icons at their display size for smoother tab edges. +Windows packages include a Pebrel installer and portable ZIP. Linux x64 packages and macOS Apple Silicon/Intel DMGs retain their Preview designation. macOS requires version 14 or later. Molecular structure rendering remains disabled. + ### 中文 #### 新增 -- 在“设置 → 交互”中加入“焦点跟随鼠标”,默认关闭;在“设置 → 外观”中加入“调暗非活动窗格”,默认开启。两项设置均即时生效。 -- Shell 启动菜单新增右键操作,可设为默认 Shell;Windows 下还可在新的管理员 Pebrel 窗口内打开所选 Shell。 -- SSH 启动菜单新增“连接、编辑、删除”右键操作;删除沿用已有的确认与撤销流程。 -- 新增 Trae CLI 识别与标签图标,并为 Oh My Pi 加入独立图标。 +- 新增:在“设置 → 交互”中加入“焦点跟随鼠标”,默认关闭;在“设置 → 外观”中加入“调暗非活动窗格”,默认开启。两项设置均即时生效。 +- 新增:Shell 启动菜单新增右键操作,可设为默认 Shell;Windows 下还可在新的管理员 Pebrel 窗口内打开所选 Shell。 +- 新增:SSH 启动菜单新增“连接、编辑、删除”右键操作;删除沿用已有的确认与撤销流程。 +- 新增: Trae CLI 识别与标签图标,并为 Oh My Pi 加入独立图标。 #### 修复 -- 修复 Windows 终端获得焦点时吞掉 `Alt+F4` 和 `Alt+Space` 的问题。`Alt+F4` 现在进入正常窗口关闭流程,`Alt+Space` 后按 `N` 可通过系统菜单最小化窗口。 -- 修复顶部设置标签在切换到其他标签后消失的问题。现在只有主动关闭才会移除,标签溢出或切换标签布局时也会保留。 -- 修复 `Alt+1–9` 和 `Ctrl+1–9` 标签快捷键优先级低于终端输入的问题。终端或 CLI 获得焦点时仍可切换标签,自定义快捷键的修改也无需重启即可生效。 +- 修复: Windows 终端获得焦点时吞掉 `Alt+F4` 和 `Alt+Space` 的问题。`Alt+F4` 现在进入正常窗口关闭流程,`Alt+Space` 后按 `N` 可通过系统菜单最小化窗口。 +- 修复:顶部设置标签在切换到其他标签后消失的问题。现在只有主动关闭才会移除,标签溢出或切换标签布局时也会保留。 +- 修复: `Alt+1–9` 和 `Ctrl+1–9` 标签快捷键优先级低于终端输入的问题。终端或 CLI 获得焦点时仍可切换标签,自定义快捷键的修改也无需重启即可生效。 +- 修复:目录路径含空格或 Shell 特殊符号时 WSL 文件名搜索失败的问题;取消搜索会停止该次目录扫描。 +- 修复:对齐 macOS 原生窗口按钮与侧栏、设置按钮,并在顶部标签布局中保留窗口按钮所需空间;窗口按钮外观跟随系统。由 [@WilliamWang1721](https://github.com/WilliamWang1721) 在 [#114](https://github.com/Kuddev/pebrel/pull/114) 中贡献。 +- 修复:应用解析为英文时 Git 面板仍保留中文标签的问题。控件、历史时间和应用提示跟随所选语言,切换语言时保留提交草稿和文字选区。由 [@gao-jian-bin](https://github.com/gao-jian-bin) 在 [#118](https://github.com/Kuddev/pebrel/pull/118) 中贡献。 +- 修复:终端忽略用户明确设置的选中文字颜色的问题。未指定选中文字颜色的主题会保留该设置;已明确指定的主题仍保持自身优先级。由 [@Aschenbath](https://github.com/Aschenbath) 在 [#125](https://github.com/Kuddev/pebrel/pull/125) 中贡献。 #### 改进 -- 将 Claude Code 的低分辨率图标替换为从 SVG 导出的 1024 像素图像,并按显示尺寸处理 Agent 图标,使标签图标边缘更平滑。 +- 改进:降低文件浏览与文件名搜索的内存占用:输入关键词后才开始递归搜索,复用有容量上限的缓存,并流式查找缓存之外的路径。重复使用文件面板时释放过期结果、取消已被替代的搜索;保留大小写、整词和正则选项,并明确提示搜索未覆盖全部文件或发生错误。 +- 改进:降低背景图内存占用,限制图片加载成本,并在调整窗口大小时复用图像资源;替换背景图会释放旧资源,扩展背景仍保持原有的适配、对齐和文字可读性。 +- 改进:将 Claude Code 的低分辨率图标替换为从 SVG 导出的 1024 像素图像,并按显示尺寸处理 Agent 图标,使标签图标边缘更平滑。 + +Windows 提供 Pebrel 安装器和 ZIP 便携包;Linux x64 包以及 macOS Apple Silicon/Intel DMG 继续标记为 Preview。macOS 最低运行版本为 14。分子结构渲染仍处于禁用状态。 + +### Contributors + +@WilliamWang1721 avatar@gao-jian-bin avatar@Aschenbath avatar + +**[@WilliamWang1721](https://github.com/WilliamWang1721)** - Aligned macOS native window controls and expanded native test coverage. / 对齐 macOS 原生窗口按钮,并扩展原生测试覆盖。([#114](https://github.com/Kuddev/pebrel/pull/114)) + +**[@gao-jian-bin](https://github.com/gao-jian-bin)** - Made Git drawer language follow application preferences while preserving editing state. / 让 Git 面板语言跟随应用设置,同时保留编辑状态。([#118](https://github.com/Kuddev/pebrel/pull/118)) + +**[@Aschenbath](https://github.com/Aschenbath)** - Preserved explicit terminal selection foreground colors. / 修正终端选中文字颜色的配置与主题优先级。([#125](https://github.com/Kuddev/pebrel/pull/125)) + + +--- + +**SHA256** + +- 改进:`Pebrel-v1.8.0-windows-x64.zip`: `PENDING FINAL BUILD` +- 改进:`Pebrel-v1.8.0-windows-x64-setup.exe`: `PENDING FINAL BUILD` +- 改进:`Pebrel-v1.8.0-linux-x64-preview.AppImage`: `PENDING FINAL BUILD` +- 改进:`Pebrel-v1.8.0-linux-x64-preview.deb`: `PENDING FINAL BUILD` +- 改进:`Pebrel-v1.8.0-linux-x64-preview.tar.gz`: `PENDING FINAL BUILD` +- 改进:`Pebrel-v1.8.0-macos-arm64-preview.dmg`: `PENDING FINAL BUILD` +- 改进:`Pebrel-v1.8.0-macos-x64-preview.dmg`: `PENDING FINAL BUILD` ## 1.7.0 - 2026-09-12 diff --git a/Cargo.lock b/Cargo.lock index 32399d6..a2c7305 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5087,7 +5087,7 @@ dependencies = [ [[package]] name = "nebula" -version = "1.7.0" +version = "1.8.0" dependencies = [ "ab_glyph_rasterizer", "aes-gcm", @@ -5174,7 +5174,7 @@ dependencies = [ [[package]] name = "nebula-completions" -version = "1.7.0" +version = "1.8.0" dependencies = [ "lscolors", "nu-ansi-term", @@ -5195,15 +5195,15 @@ dependencies = [ [[package]] name = "nebula-settings" -version = "1.7.0" +version = "1.8.0" [[package]] name = "nebula-split" -version = "1.7.0" +version = "1.8.0" [[package]] name = "nebula_config" -version = "1.7.0" +version = "1.8.0" dependencies = [ "log", "nebula_config_derive", @@ -5213,7 +5213,7 @@ dependencies = [ [[package]] name = "nebula_config_derive" -version = "1.7.0" +version = "1.8.0" dependencies = [ "log", "nebula_config", @@ -5230,7 +5230,7 @@ version = "0.6.0" [[package]] name = "nebula_terminal" -version = "1.7.0" +version = "1.8.0" dependencies = [ "base64", "bitflags 2.13.0", diff --git a/Cargo.toml b/Cargo.toml index 454a063..d98a66b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,8 @@ edition = "2024" rust-version = "1.97.1" [profile.release] -# fat LTO 会用顶层 opt-level 重跑全程序 codegen,把下面的热路径 O3 钉子 -# 冲掉;thin + codegen-units=1 保住钉子,体积差距只有个位数百分点。 +# Thin LTO preserves package-specific optimization levels. Dependencies retain +# one codegen unit; the application uses parallel codegen with the same O3 level. lto = "thin" debug = 0 strip = "symbols" @@ -38,7 +38,7 @@ smol = { opt-level = 3 } gpui = { opt-level = 3 } gpui-component = { opt-level = 3 } nebula_terminal = { opt-level = 3 } -nebula = { opt-level = 3 } +nebula = { opt-level = 3, codegen-units = 16 } image = { opt-level = 3 } # Debug 壳仍要承担真实终端负载:GPUI 布局/字体塑形和 VT 解析若以 diff --git a/docs/architecture-decisions.md b/docs/architecture-decisions.md index bf67bb8..c9b7ca4 100644 --- a/docs/architecture-decisions.md +++ b/docs/architecture-decisions.md @@ -420,3 +420,36 @@ settings files. - **Replacement condition:** Revisit the budgets or an OS-backed index only with measured query latency, completeness and sustained allocation evidence. Do not restore eager full-tree indexing to improve a synthetic latency number. + +## ADR-0014 — Parallel release validation with one product build graph + +- **Date:** 2026-09-14 +- **Context:** The 1.7.0 Windows release job took 41m28s despite a full dependency + cache hit. Its logs show three application test compilations (4m44s, 9m16s and + 4m07s), a 15m08s release build, and 4m16s of additional dependency compilation + during packaging. The user requested a slowest-job target of ten minutes. +- **Decision:** Run the complete Rust workspace with the product interaction + feature enabled in one unfiltered invocation. Run native tests independently + from package construction; asset aggregation depends on both. Each native + platform still runs the complete Python helper and harness suites. Cache keys + preserve the existing platform namespace and retain workspace crates. Cargo + still validates source, profile and feature fingerprints before reuse. +- **Product compilation:** The application keeps O3 and Thin LTO and uses 16 + codegen units to parallelize its large translation unit. Other package settings + retain their existing values. Both Windows packagers call one explicit builder + for the product and its packaged hook, preserving the same feature graph. + Packaging still invokes Cargo and validates source freshness and binary identity. +- **Contract clarification:** The old packaging test required the literal + `--workspace --exclude nebula`, rejecting a valid explicit selection of the two + shipped binaries. It now verifies the actual selected packages, binaries and + product feature, plus failure propagation and restoration of the caller's target. + No test filtering, freshness bypass, size-budget increase or dependency change + is part of this decision. +- **Validation:** The release pipeline runs native tests, packaging fixtures, + package-size/identity checks and installed or mounted conformance on all four + platforms. Actual job timings determine whether the target is met; cache input + changes and first compilation must be reported separately. A configured timeout + or parallel scheduling alone is not evidence of a ten-minute successful build. +- **Revisit condition:** Retain only changes whose complete CI run and package + checks pass. Reconsider codegen partitioning if artifact size or runtime + measurements regress, and remove redundant caches if restore/save cost grows. diff --git a/docs/release-notes/v1.8.0.md b/docs/release-notes/v1.8.0.md new file mode 100644 index 0000000..c402f79 --- /dev/null +++ b/docs/release-notes/v1.8.0.md @@ -0,0 +1,78 @@ +# Pebrel 1.8.0 + +## English + +### Added + +- Added “Focus follows mouse” in Settings → Interaction, off by default, and “Dim inactive panes” in Settings → Appearance, on by default. Both preferences take effect immediately. +- Added right-click actions to the Shell launcher for choosing the default Shell and, on Windows, opening the selected Shell inside a new administrator Pebrel window. +- Added Connect, Edit, and Delete to SSH launcher context menus. Delete uses the existing confirmation and undo flow. +- Added Trae CLI recognition and its tab icon, plus a dedicated Oh My Pi icon. + +### Fixed + +- Fixed Windows terminal focus consuming `Alt+F4` and `Alt+Space`. `Alt+F4` now uses the normal window-close flow, and `Alt+Space`, followed by `N`, uses the system menu to minimize the window. +- Fixed the top Settings tab disappearing when switching to another tab. It now remains available until explicitly closed, including when tabs overflow or the tab layout changes. +- Fixed `Alt+1–9` and `Ctrl+1–9` tab shortcuts losing priority to terminal input. They now work while a terminal or CLI has focus and respect custom shortcut changes without restarting. +- Fixed WSL filename search failing when the directory path contains spaces or shell punctuation. Cancelling a search stops its own directory scan. +- Aligned macOS native window controls with the sidebar and Settings buttons, and preserved their reserved space in the top tab layout. Window controls follow the system appearance. Contributed by [@WilliamWang1721](https://github.com/WilliamWang1721) in [#114](https://github.com/Kuddev/pebrel/pull/114). +- Fixed the Git drawer retaining Chinese labels when the application resolves to English. Controls, history timestamps and application notices follow the selected language; switching languages preserves the commit draft and text selection. Contributed by [@gao-jian-bin](https://github.com/gao-jian-bin) in [#118](https://github.com/Kuddev/pebrel/pull/118). +- Fixed explicitly configured terminal selection text colors being ignored. Themes without their own selection foreground preserve that setting; themes with an explicit foreground retain their precedence. Contributed by [@Aschenbath](https://github.com/Aschenbath) in [#125](https://github.com/Kuddev/pebrel/pull/125). + +### Improved + +- Reduced file browsing and filename-search memory use by starting recursive searches only when a query is entered, reusing a bounded cache and streaming paths beyond that cache. Repeated panel use releases obsolete results and cancels superseded searches. Case, whole-word and regular-expression options remain available, with visible feedback for incomplete searches and errors. +- Reduced background-image memory use with bounded image loading and reuse while resizing the window. Replacing an image releases the previous resources; extended backgrounds retain their fit, alignment and text readability. +- Replaced the low-resolution Claude Code icon with artwork exported from SVG at 1024 pixels, and prepared Agent icons at their display size for smoother tab edges. + +Windows packages include a Pebrel installer and portable ZIP. Linux x64 packages and macOS Apple Silicon/Intel DMGs retain their Preview designation. macOS requires version 14 or later. Molecular structure rendering remains disabled. + +## 中文 + +### 新增 + +- 新增:在“设置 → 交互”中加入“焦点跟随鼠标”,默认关闭;在“设置 → 外观”中加入“调暗非活动窗格”,默认开启。两项设置均即时生效。 +- 新增:Shell 启动菜单新增右键操作,可设为默认 Shell;Windows 下还可在新的管理员 Pebrel 窗口内打开所选 Shell。 +- 新增:SSH 启动菜单新增“连接、编辑、删除”右键操作;删除沿用已有的确认与撤销流程。 +- 新增: Trae CLI 识别与标签图标,并为 Oh My Pi 加入独立图标。 + +### 修复 + +- 修复: Windows 终端获得焦点时吞掉 `Alt+F4` 和 `Alt+Space` 的问题。`Alt+F4` 现在进入正常窗口关闭流程,`Alt+Space` 后按 `N` 可通过系统菜单最小化窗口。 +- 修复:顶部设置标签在切换到其他标签后消失的问题。现在只有主动关闭才会移除,标签溢出或切换标签布局时也会保留。 +- 修复: `Alt+1–9` 和 `Ctrl+1–9` 标签快捷键优先级低于终端输入的问题。终端或 CLI 获得焦点时仍可切换标签,自定义快捷键的修改也无需重启即可生效。 +- 修复:目录路径含空格或 Shell 特殊符号时 WSL 文件名搜索失败的问题;取消搜索会停止该次目录扫描。 +- 修复:对齐 macOS 原生窗口按钮与侧栏、设置按钮,并在顶部标签布局中保留窗口按钮所需空间;窗口按钮外观跟随系统。由 [@WilliamWang1721](https://github.com/WilliamWang1721) 在 [#114](https://github.com/Kuddev/pebrel/pull/114) 中贡献。 +- 修复:应用解析为英文时 Git 面板仍保留中文标签的问题。控件、历史时间和应用提示跟随所选语言,切换语言时保留提交草稿和文字选区。由 [@gao-jian-bin](https://github.com/gao-jian-bin) 在 [#118](https://github.com/Kuddev/pebrel/pull/118) 中贡献。 +- 修复:终端忽略用户明确设置的选中文字颜色的问题。未指定选中文字颜色的主题会保留该设置;已明确指定的主题仍保持自身优先级。由 [@Aschenbath](https://github.com/Aschenbath) 在 [#125](https://github.com/Kuddev/pebrel/pull/125) 中贡献。 + +### 改进 + +- 改进:降低文件浏览与文件名搜索的内存占用:输入关键词后才开始递归搜索,复用有容量上限的缓存,并流式查找缓存之外的路径。重复使用文件面板时释放过期结果、取消已被替代的搜索;保留大小写、整词和正则选项,并明确提示搜索未覆盖全部文件或发生错误。 +- 改进:降低背景图内存占用,限制图片加载成本,并在调整窗口大小时复用图像资源;替换背景图会释放旧资源,扩展背景仍保持原有的适配、对齐和文字可读性。 +- 改进:将 Claude Code 的低分辨率图标替换为从 SVG 导出的 1024 像素图像,并按显示尺寸处理 Agent 图标,使标签图标边缘更平滑。 + +Windows 提供 Pebrel 安装器和 ZIP 便携包;Linux x64 包以及 macOS Apple Silicon/Intel DMG 继续标记为 Preview。macOS 最低运行版本为 14。分子结构渲染仍处于禁用状态。 + +## Contributors + +@WilliamWang1721 avatar@gao-jian-bin avatar@Aschenbath avatar + +**[@WilliamWang1721](https://github.com/WilliamWang1721)** - Aligned macOS native window controls and expanded native test coverage. / 对齐 macOS 原生窗口按钮,并扩展原生测试覆盖。([#114](https://github.com/Kuddev/pebrel/pull/114)) + +**[@gao-jian-bin](https://github.com/gao-jian-bin)** - Made Git drawer language follow application preferences while preserving editing state. / 让 Git 面板语言跟随应用设置,同时保留编辑状态。([#118](https://github.com/Kuddev/pebrel/pull/118)) + +**[@Aschenbath](https://github.com/Aschenbath)** - Preserved explicit terminal selection foreground colors. / 修正终端选中文字颜色的配置与主题优先级。([#125](https://github.com/Kuddev/pebrel/pull/125)) + + +--- + +**SHA256** + +- `Pebrel-v1.8.0-windows-x64.zip`: `PENDING FINAL BUILD` +- `Pebrel-v1.8.0-windows-x64-setup.exe`: `PENDING FINAL BUILD` +- `Pebrel-v1.8.0-linux-x64-preview.AppImage`: `PENDING FINAL BUILD` +- `Pebrel-v1.8.0-linux-x64-preview.deb`: `PENDING FINAL BUILD` +- `Pebrel-v1.8.0-linux-x64-preview.tar.gz`: `PENDING FINAL BUILD` +- `Pebrel-v1.8.0-macos-arm64-preview.dmg`: `PENDING FINAL BUILD` +- `Pebrel-v1.8.0-macos-x64-preview.dmg`: `PENDING FINAL BUILD` diff --git a/nebula-completions/Cargo.toml b/nebula-completions/Cargo.toml index 75e2541..d550f62 100644 --- a/nebula-completions/Cargo.toml +++ b/nebula-completions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula-completions" -version = "1.7.0" +version = "1.8.0" edition.workspace = true [features] diff --git a/nebula_app/Cargo.toml b/nebula_app/Cargo.toml index 451a293..93a8151 100644 --- a/nebula_app/Cargo.toml +++ b/nebula_app/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0-or-later" description = "Pebrel — a GPU-accelerated terminal emulator" readme = "README.md" @@ -15,15 +15,15 @@ path = "src/main.rs" [dependencies.nebula_terminal] path = "../nebula_terminal" -version = "1.7.0" +version = "1.8.0" [dependencies.nebula_config_derive] path = "../nebula_config_derive" -version = "1.7.0" +version = "1.8.0" [dependencies.nebula_config] path = "../nebula_config" -version = "1.7.0" +version = "1.8.0" # 可选:GPUI UI 层(feature = "gpui-shell",模块 src/gpui_shell/)。 # GPUI/component 的版本和 Git 来源由根 Cargo.toml 统一精确固定。 @@ -67,7 +67,7 @@ optional = true [dependencies.nebula-completions] path = "../nebula-completions" -version = "1.7.0" +version = "1.8.0" [dependencies] ahash = { version = "0.8.6", features = ["no-rng"] } @@ -141,7 +141,7 @@ rusqlite = { version = "0.40.2", features = ["bundled"] } sha1 = "0.11.0" [build-dependencies] -nebula-settings = { path = "../nebula_settings", version = "1.7.0" } +nebula-settings = { path = "../nebula_settings", version = "1.8.0" } gl_generator = { version = "0.14.0", optional = true } serde = "1" serde_json = "1" diff --git a/nebula_app/windows/nebula.rc b/nebula_app/windows/nebula.rc index e167b42..5ed706b 100644 --- a/nebula_app/windows/nebula.rc +++ b/nebula_app/windows/nebula.rc @@ -10,8 +10,8 @@ APP_MANIFEST RT_MANIFEST nebula.manifest #endif 1 VERSIONINFO -FILEVERSION 1,7,0,0 -PRODUCTVERSION 1,7,0,0 +FILEVERSION 1,8,0,0 +PRODUCTVERSION 1,8,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -24,11 +24,11 @@ BEGIN BEGIN VALUE "CompanyName", "Kuddev" VALUE "FileDescription", "Pebrel" - VALUE "FileVersion", "1.7.0" + VALUE "FileVersion", "1.8.0" VALUE "InternalName", "nebula" VALUE "OriginalFilename", "pebrel.exe" VALUE "ProductName", "Pebrel" - VALUE "ProductVersion", "1.7.0" + VALUE "ProductVersion", "1.8.0" END END BLOCK "VarFileInfo" diff --git a/nebula_config/Cargo.toml b/nebula_config/Cargo.toml index dbd27a6..dc15094 100644 --- a/nebula_config/Cargo.toml +++ b/nebula_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula_config" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0-or-later" description = "Nebula configuration abstractions" homepage = "https://github.com/Kuddev/pebrel" @@ -14,5 +14,5 @@ serde = "1.0.163" toml.workspace = true [dev-dependencies] -nebula_config_derive = { version = "1.7.0", path = "../nebula_config_derive" } +nebula_config_derive = { version = "1.8.0", path = "../nebula_config_derive" } serde = { version = "1.0.163", features = ["derive"] } diff --git a/nebula_config_derive/Cargo.toml b/nebula_config_derive/Cargo.toml index fc5d038..2828977 100644 --- a/nebula_config_derive/Cargo.toml +++ b/nebula_config_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula_config_derive" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0-or-later" description = "Failure resistant deserialization derive" homepage = "https://github.com/Kuddev/pebrel" @@ -18,7 +18,7 @@ syn = { version = "2.0.16", features = ["derive", "parsing", "proc-macro", "prin [dev-dependencies.nebula_config] path = "../nebula_config" -version = "1.7.0" +version = "1.8.0" [dev-dependencies] log = "0.4.11" diff --git a/nebula_settings/Cargo.toml b/nebula_settings/Cargo.toml index 43cfcce..c7c29f3 100644 --- a/nebula_settings/Cargo.toml +++ b/nebula_settings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula-settings" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0-or-later" description = "Shared reader for Nebula runtime user settings (nebula_settings.txt) and theme terminal-color tables" publish = false diff --git a/nebula_split/Cargo.toml b/nebula_split/Cargo.toml index b1fa368..f57f9fe 100644 --- a/nebula_split/Cargo.toml +++ b/nebula_split/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula-split" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0-or-later" description = "Shared split-pane rules: layout tree, geometry, divider drag and directional focus" publish = false diff --git a/nebula_terminal/Cargo.toml b/nebula_terminal/Cargo.toml index 8a40565..b712354 100644 --- a/nebula_terminal/Cargo.toml +++ b/nebula_terminal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nebula_terminal" -version = "1.7.0" +version = "1.8.0" license = "GPL-3.0-or-later" description = "Nebula terminal emulation core" readme = "../README.md" diff --git a/scripts/build-installer.ps1 b/scripts/build-installer.ps1 index 2d3040c..55112b3 100644 --- a/scripts/build-installer.ps1 +++ b/scripts/build-installer.ps1 @@ -85,28 +85,7 @@ if (-not (Test-Path -LiteralPath $installerScript -PathType Leaf)) { } if (-not $SkipBuild) { - Push-Location $repo - $previousTargetDirectory = $env:CARGO_TARGET_DIR - try { - $env:CARGO_TARGET_DIR = $cargoTargetRoot - $workspaceArgs = @('build', '--workspace', '--exclude', 'nebula', '--locked') - $gpuiArgs = @('build', '-p', 'nebula', '--bin', 'pebrel', '--features', 'gpui-shell', '--locked') - if ($Configuration -eq 'release') { - $workspaceArgs += '--release' - $gpuiArgs += '--release' - } - & cargo @workspaceArgs - if ($LASTEXITCODE -ne 0) { - throw "Cargo workspace build failed with exit code $LASTEXITCODE" - } - & cargo @gpuiArgs - if ($LASTEXITCODE -ne 0) { - throw "Cargo gpui-shell build failed with exit code $LASTEXITCODE" - } - } finally { - $env:CARGO_TARGET_DIR = $previousTargetDirectory - Pop-Location - } + & (Join-Path $PSScriptRoot 'build-windows-product.ps1') -Configuration $Configuration -TargetDirectory $cargoTargetRoot } $missing = @($requiredFiles | Where-Object { -not (Test-Path -LiteralPath $_ -PathType Leaf) }) diff --git a/scripts/build-windows-product.ps1 b/scripts/build-windows-product.ps1 new file mode 100644 index 0000000..89367e2 --- /dev/null +++ b/scripts/build-windows-product.ps1 @@ -0,0 +1,36 @@ +[CmdletBinding()] +param( + [ValidateSet('debug', 'release')] + [string] $Configuration = 'release', + [string] $TargetDirectory +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest +$repo = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path +if ([string]::IsNullOrWhiteSpace($TargetDirectory)) { + $TargetDirectory = Join-Path $repo 'target' +} elseif (-not [IO.Path]::IsPathRooted($TargetDirectory)) { + $TargetDirectory = Join-Path $repo $TargetDirectory +} +$previousTargetDirectory = $env:CARGO_TARGET_DIR +Push-Location $repo +try { + $env:CARGO_TARGET_DIR = [IO.Path]::GetFullPath($TargetDirectory) + # Keep the feature graph identical for the initial build, ZIP and installer. + # The acceptance lab is tested by CI but does not supply a packaged binary. + $arguments = @( + 'build', '--locked', '--timings', + '-p', 'nebula', '--bin', 'pebrel', + '-p', 'nebula_hook', '--bin', 'pebrel-hook', + '--features', 'nebula/gpui-shell' + ) + if ($Configuration -eq 'release') { $arguments += '--release' } + & cargo @arguments + if ($LASTEXITCODE -ne 0) { + throw "Cargo Windows product build failed with exit code $LASTEXITCODE" + } +} finally { + $env:CARGO_TARGET_DIR = $previousTargetDirectory + Pop-Location +} diff --git a/scripts/ci_native_tests.py b/scripts/ci_native_tests.py new file mode 100644 index 0000000..8e5545b --- /dev/null +++ b/scripts/ci_native_tests.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +"""Run the complete native suite with one Rust workspace feature graph.""" + +from __future__ import annotations + +import subprocess +import sys + + +def native_commands() -> list[list[str]]: + return [ + [sys.executable, "-m", "unittest", "discover", "-s", "scripts/tests", "-v"], + [sys.executable, "-m", "unittest", "discover", "-s", "scripts/conformance/tests", "-v"], + [ + "cargo", "test", "--locked", "--workspace", + "--features", "nebula/gpui-test-support", "--timings", + ], + ] + + +def main() -> int: + for command in native_commands(): + print("Running:", " ".join(command), flush=True) + subprocess.run(command, check=True) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/installer.iss b/scripts/installer.iss index f8a9fbb..6fc0299 100644 --- a/scripts/installer.iss +++ b/scripts/installer.iss @@ -1,9 +1,9 @@ -#ifndef AppVersion - #define AppVersion "1.7.0" +#ifndef AppVersion + #define AppVersion "1.8.0" #endif #ifndef NumericVersion - #define NumericVersion "1.7.0.0" + #define NumericVersion "1.8.0.0" #endif #ifndef Configuration diff --git a/scripts/package-release.ps1 b/scripts/package-release.ps1 index 400d7b8..671146d 100644 --- a/scripts/package-release.ps1 +++ b/scripts/package-release.ps1 @@ -144,33 +144,7 @@ function Assert-FreshBinaries { } if (-not $SkipBuild) { - Push-Location $repo - $previousTargetDirectory = $env:CARGO_TARGET_DIR - try { - $env:CARGO_TARGET_DIR = $cargoTargetRoot - # Never build nebula without gpui-shell first: a workspace default - # binary overwrites the product exe with the legacy winit shell. - # Exclude nebula from the workspace build, then link GPUI last. - if ($Configuration -eq 'release') { - & cargo build --workspace --release --exclude nebula --locked - if ($LASTEXITCODE -ne 0) { - throw "Cargo workspace build failed with exit code $LASTEXITCODE" - } - & cargo build -p nebula --bin pebrel --release --features gpui-shell --locked - } else { - & cargo build --workspace --exclude nebula --locked - if ($LASTEXITCODE -ne 0) { - throw "Cargo workspace build failed with exit code $LASTEXITCODE" - } - & cargo build -p nebula --bin pebrel --features gpui-shell --locked - } - if ($LASTEXITCODE -ne 0) { - throw "Cargo gpui-shell build failed with exit code $LASTEXITCODE" - } - } finally { - $env:CARGO_TARGET_DIR = $previousTargetDirectory - Pop-Location - } + & (Join-Path $PSScriptRoot 'build-windows-product.ps1') -Configuration $Configuration -TargetDirectory $cargoTargetRoot } $missing = @($manifest.GetEnumerator() | Where-Object { diff --git a/scripts/tests/build-windows-product.tests.ps1 b/scripts/tests/build-windows-product.tests.ps1 new file mode 100644 index 0000000..d236a97 --- /dev/null +++ b/scripts/tests/build-windows-product.tests.ps1 @@ -0,0 +1,44 @@ +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest +$builder = Join-Path $PSScriptRoot '../build-windows-product.ps1' +$originalTarget = $env:CARGO_TARGET_DIR +$originalDirectory = (Get-Location).Path +$global:ProductBuildCalls = @() +$global:ProductBuildExit = 0 +function global:cargo { + $global:ProductBuildCalls += ,@($args) + $global:LASTEXITCODE = $global:ProductBuildExit +} +try { + $env:CARGO_TARGET_DIR = 'preserve-caller-target' + & $builder -Configuration release -TargetDirectory target + if ($global:ProductBuildCalls.Count -ne 1) { throw 'Expected one product build' } + $arguments = $global:ProductBuildCalls[0] + $packages = @(); $binaries = @() + for ($i = 0; $i -lt $arguments.Count - 1; $i++) { + if ($arguments[$i] -eq '-p') { $packages += $arguments[$i + 1] } + if ($arguments[$i] -eq '--bin') { $binaries += $arguments[$i + 1] } + } + if (($packages -join ',') -ne 'nebula,nebula_hook') { throw 'Unexpected package selection' } + if (($binaries -join ',') -ne 'pebrel,pebrel-hook') { throw 'Unexpected product binaries' } + foreach ($required in @('--locked', '--release', '--features', 'nebula/gpui-shell')) { + if ($required -notin $arguments) { throw "Missing product build argument: $required" } + } + if ('--workspace' -in $arguments) { throw 'Packaging must not build the acceptance lab' } + if ($env:CARGO_TARGET_DIR -ne 'preserve-caller-target') { throw 'Caller target changed' } + & $builder -Configuration debug -TargetDirectory target + if ('--release' -in $global:ProductBuildCalls[1]) { throw 'Debug build selected release' } + $global:ProductBuildExit = 27 + $failed = $false + try { & $builder -Configuration release -TargetDirectory target } catch { + $failed = $_.Exception.Message -match 'exit code 27' + } + if (-not $failed) { throw 'Cargo failure must fail packaging' } + if ($env:CARGO_TARGET_DIR -ne 'preserve-caller-target') { throw 'Failure changed caller target' } + if ((Get-Location).Path -ne $originalDirectory) { throw 'Failure changed caller directory' } + Write-Output 'build-windows-product.tests.ps1: PASS' +} finally { + $env:CARGO_TARGET_DIR = $originalTarget + Remove-Item Function:\cargo + Remove-Variable ProductBuildCalls,ProductBuildExit -Scope Global +} diff --git a/scripts/tests/package-release.tests.ps1 b/scripts/tests/package-release.tests.ps1 index 6226ccb..615aff3 100644 --- a/scripts/tests/package-release.tests.ps1 +++ b/scripts/tests/package-release.tests.ps1 @@ -38,15 +38,10 @@ try { } $scriptBody = Get-Content -LiteralPath $packageScript -Raw -Encoding UTF8 - if ($scriptBody -notmatch '--features gpui-shell') { - throw 'Release packaging must rebuild Pebrel with --features gpui-shell so the zip ships the GPUI shell.' - } - if ($scriptBody -notmatch '--bin pebrel') { - throw 'Release packaging must build the Pebrel product executable.' - } - if ($scriptBody -notmatch '--exclude nebula') { - throw 'Release packaging must exclude nebula from the workspace build so the default-feature binary cannot overwrite the GPUI shell.' + if ($scriptBody -notmatch 'build-windows-product.ps1') { + throw 'Release packaging must use the shared explicit product build.' } + & (Join-Path $PSScriptRoot 'build-windows-product.tests.ps1') if ($scriptBody -notmatch 'Assert-FreshBinaries') { throw 'Release packaging must refuse stale binaries (freshness guard missing).' diff --git a/scripts/tests/test_ci_native_tests.py b/scripts/tests/test_ci_native_tests.py new file mode 100644 index 0000000..4f25da8 --- /dev/null +++ b/scripts/tests/test_ci_native_tests.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +import subprocess +import unittest +from unittest.mock import patch + +from scripts.ci_native_tests import main, native_commands + + +class NativeSuiteTests(unittest.TestCase): + def test_full_workspace_and_interactions_share_one_unfiltered_invocation(self): + rust = [command for command in native_commands() if command[0] == "cargo"] + self.assertEqual(len(rust), 1) + command = rust[0] + self.assertEqual(command[1], "test") + self.assertIn("--locked", command) + self.assertIn("--workspace", command) + self.assertEqual(command[command.index("--features") + 1], "nebula/gpui-test-support") + self.assertNotIn("--exclude", command) + self.assertNotIn("--lib", command) + self.assertNotIn("--skip", command) + self.assertNotIn("--", command) + + def test_both_python_test_roots_are_discovered(self): + suites = [command for command in native_commands() if "unittest" in command] + self.assertEqual( + {command[command.index("-s") + 1] for command in suites}, + {"scripts/tests", "scripts/conformance/tests"}, + ) + self.assertTrue(all("discover" in command for command in suites)) + + def test_success_runs_every_command_and_checks_exit_codes(self): + with patch("scripts.ci_native_tests.subprocess.run") as run: + self.assertEqual(main(), 0) + self.assertEqual(run.call_count, len(native_commands())) + self.assertTrue(all(call.kwargs["check"] for call in run.call_args_list)) + + def test_failure_stops_the_suite_and_is_not_reported_as_success(self): + with patch("scripts.ci_native_tests.subprocess.run") as run: + run.side_effect = subprocess.CalledProcessError(7, "test") + with self.assertRaises(subprocess.CalledProcessError): + main() + self.assertEqual(run.call_count, 1) + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/tests/test_stable_release.py b/scripts/tests/test_stable_release.py index e73dd17..7dd1fd6 100644 --- a/scripts/tests/test_stable_release.py +++ b/scripts/tests/test_stable_release.py @@ -68,21 +68,17 @@ def notes(checksum_placeholder: bool = True) -> str: class StableReleaseTests(unittest.TestCase): - def test_stable_workflow_runs_gpui_interaction_tests_on_every_platform(self) -> None: + def test_stable_workflow_requires_full_native_tests_before_aggregation(self) -> None: root = Path(__file__).resolve().parents[2] workflow = (root / ".github/workflows/release.yml").read_text(encoding="utf-8") - command = "cargo test --locked -p nebula --bin pebrel --features gpui-test-support gpui_shell::" - self.assertEqual(workflow.count(command), 3) - windows_step = workflow.split(" - name: Test workspace and native harness\n", 1)[1] - windows_step = windows_step.split(" - name:", 1)[0] - self.assertIn("shell: pwsh", windows_step) - lines = [line.strip() for line in windows_step.splitlines()] - commands = 0 - for index, line in enumerate(lines): - if line.startswith(("cargo test ", "python -m unittest ")): - commands += 1 - self.assertEqual(lines[index + 1], "if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }") - self.assertEqual(commands, 5) + native = workflow.split(" native-tests:\n", 1)[1].split("\n linux:\n", 1)[0] + for platform in ("linux-x64", "windows-x64", "macos-arm64", "macos-x64"): + self.assertIn("platform: " + platform, native) + self.assertIn("run: python scripts/ci_native_tests.py", native) + self.assertNotIn("continue-on-error", native) + aggregate = workflow.split("\n aggregate:\n", 1)[1].split("\n publish:\n", 1)[0] + self.assertIn("needs: [prepare, native-tests, linux, macos, windows]", aggregate) + self.assertNotIn("always()", aggregate) def test_native_packagers_expose_stable_channel_without_preview_id(self) -> None: root = Path(__file__).resolve().parents[2] diff --git a/tools/i18n-contract/Cargo.lock b/tools/i18n-contract/Cargo.lock index fef745b..f055b79 100644 --- a/tools/i18n-contract/Cargo.lock +++ b/tools/i18n-contract/Cargo.lock @@ -16,7 +16,7 @@ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "nebula-settings" -version = "1.7.0" +version = "1.8.0" [[package]] name = "pebrel-i18n-contract"