From bc4865b3e60892764cb5347cfb6cd8aa9272b226 Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 19 Oct 2026 18:30:06 -0400 Subject: [PATCH 1/6] fix(desktop): prepare a release on a CRLF checkout Git on Windows checks files out with CRLF, and the Cargo.toml and Cargo.lock version patterns required LF, so prepare_release.py raised "could not rewrite package version" and the Windows engine tests failed on main (job 118266645919). The patterns now accept CRLF and keep each line's ending. A new test converts every version file to CRLF, so the Linux lane catches this too. Co-Authored-By: Claude Opus 5.5 --- packages/desktop/scripts/native_release.py | 11 ++++++++--- packages/desktop/tests/test_release_intent.py | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/desktop/scripts/native_release.py b/packages/desktop/scripts/native_release.py index 35a7d6767..d3baf61c9 100644 --- a/packages/desktop/scripts/native_release.py +++ b/packages/desktop/scripts/native_release.py @@ -271,7 +271,9 @@ def set_native_version(version: str, root: Path = ROOT) -> dict[str, str]: result with the Git blobs of the candidate tag. Text-mode I/O would break that: on Windows it rewrites every ``\\n`` as ``\\r\\n``, and an omitted encoding decodes with the locale default. All reads and writes below are - therefore explicit UTF-8 bytes with LF endings. + therefore explicit UTF-8 bytes with LF endings. The Cargo patterns also + accept CRLF, because Git on Windows checks files out with CRLF by default, + and they keep whatever ending each line already has. """ if not VERSION_PATTERN.fullmatch(version): @@ -301,7 +303,10 @@ def set_lock_versions(lock: dict) -> None: cargo_toml = root / "src-tauri" / "Cargo.toml" text, replaced = re.subn( - r'(?m)^version = "[^"]+"$', f'version = "{version}"', read_source(cargo_toml), count=1 + r'(?m)^version = "[^"]+"(?=\r?$)', + f'version = "{version}"', + read_source(cargo_toml), + count=1, ) if replaced != 1: raise ValueError(f"could not rewrite package version in {cargo_toml}") @@ -309,7 +314,7 @@ def set_lock_versions(lock: dict) -> None: cargo_lock = root / "src-tauri" / "Cargo.lock" text, replaced = re.subn( - r'(name = "openadapt-desktop"\nversion = ")[^"]+(")', + r'(name = "openadapt-desktop"\r?\nversion = ")[^"]+(")', rf"\g<1>{version}\g<2>", read_source(cargo_lock), count=1, diff --git a/packages/desktop/tests/test_release_intent.py b/packages/desktop/tests/test_release_intent.py index 3d949247b..7d65b34c6 100644 --- a/packages/desktop/tests/test_release_intent.py +++ b/packages/desktop/tests/test_release_intent.py @@ -119,6 +119,21 @@ def test_prepare_sets_every_version_source_and_the_changelog(repo: Path) -> None assert "explain the portal" not in changelog +def test_prepare_works_on_a_crlf_checkout(repo: Path) -> None: + """Git on Windows checks files out with CRLF; every version source must still move.""" + + for relative in VERSION_FILES: + path = repo / relative + path.write_bytes(path.read_bytes().replace(b"\r\n", b"\n").replace(b"\n", b"\r\n")) + _commit(repo, "chore: check out with CRLF") + _commit(repo, "fix(portal): keep the card", touch="src/portal.txt") + + version = prepare_release.prepare(repo, today=datetime.date(2026, 10, 19)) + + assert set(check_release_consistency.release_versions(repo).values()) == {version} + assert _load("native_release").native_version(repo) == version + + def test_prepare_refuses_without_a_releasable_commit(repo: Path) -> None: _commit(repo, "docs: only words", touch="docs/words.md") with pytest.raises(ValueError, match="no feat, fix, perf"): From d433a013317539697d6ab9491d09e467c03e845f Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 19 Oct 2026 18:30:06 -0400 Subject: [PATCH 2/6] fix(desktop): supply the reviewed PyObjC license for the 12.2.2 wheels The macOS sidecar and installer builds stopped with "pyobjc-core has no concrete license/NOTICE file" (jobs 118267947313, 118267947454). The lock moved pyobjc-core to 12.2.2 and added pyobjc-framework-CoreMedia and -ScreenCaptureKit 12.2.2, and none of those wheels ships a license file, while the reviewed records covered only 12.2.1. Upstream's License.txt for all three at tag v12.2.2 (commit 38cdf73) is byte-identical to the vendored third_party/pyobjc/LICENSE.txt (SHA-256 0ca04b07...), and each wheel's license metadata is the reviewed "MIT". The records pin the source URL, commit, text hash and metadata hash per version, as for 12.2.1. The check itself is unchanged. Co-Authored-By: Claude Opus 5.5 --- packages/desktop/scripts/frozen_notices.py | 42 ++++++++++++++++++++++ packages/desktop/third_party/README.md | 29 ++++++++------- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/packages/desktop/scripts/frozen_notices.py b/packages/desktop/scripts/frozen_notices.py index d0ccb7aa9..05c58a792 100644 --- a/packages/desktop/scripts/frozen_notices.py +++ b/packages/desktop/scripts/frozen_notices.py @@ -268,6 +268,48 @@ def capture_floor_is_satisfied(candidate: str, floor: str) -> bool: "e5dcffe836b6ec8a58e492419b550e65fb8cbdc308503979e5dacb33ac7ea3b7" ), }, + ("pyobjc-core", "12.2.2"): { + "relative_path": "pyobjc/LICENSE.txt", + "source_url": ( + "https://github.com/ronaldoussoren/pyobjc/blob/" + "38cdf73fc049ef2d176973eff4ac8d5c76b0a34b/" + "pyobjc-core/License.txt" + ), + "source_commit": "38cdf73fc049ef2d176973eff4ac8d5c76b0a34b", + "sha256": "0ca04b07928d4872b9d9bb22187ca0426dd8bfab08f26eada0999a71dc81aaff", + "license_expression": "MIT", + "license_evidence_sha256": ( + "e5dcffe836b6ec8a58e492419b550e65fb8cbdc308503979e5dacb33ac7ea3b7" + ), + }, + ("pyobjc-framework-coremedia", "12.2.2"): { + "relative_path": "pyobjc/LICENSE.txt", + "source_url": ( + "https://github.com/ronaldoussoren/pyobjc/blob/" + "38cdf73fc049ef2d176973eff4ac8d5c76b0a34b/" + "pyobjc-framework-CoreMedia/License.txt" + ), + "source_commit": "38cdf73fc049ef2d176973eff4ac8d5c76b0a34b", + "sha256": "0ca04b07928d4872b9d9bb22187ca0426dd8bfab08f26eada0999a71dc81aaff", + "license_expression": "MIT", + "license_evidence_sha256": ( + "e5dcffe836b6ec8a58e492419b550e65fb8cbdc308503979e5dacb33ac7ea3b7" + ), + }, + ("pyobjc-framework-screencapturekit", "12.2.2"): { + "relative_path": "pyobjc/LICENSE.txt", + "source_url": ( + "https://github.com/ronaldoussoren/pyobjc/blob/" + "38cdf73fc049ef2d176973eff4ac8d5c76b0a34b/" + "pyobjc-framework-ScreenCaptureKit/License.txt" + ), + "source_commit": "38cdf73fc049ef2d176973eff4ac8d5c76b0a34b", + "sha256": "0ca04b07928d4872b9d9bb22187ca0426dd8bfab08f26eada0999a71dc81aaff", + "license_expression": "MIT", + "license_evidence_sha256": ( + "e5dcffe836b6ec8a58e492419b550e65fb8cbdc308503979e5dacb33ac7ea3b7" + ), + }, ("rapidocr-onnxruntime", "1.4.4"): { "relative_path": "rapidocr/LICENSE", "source_url": ( diff --git a/packages/desktop/third_party/README.md b/packages/desktop/third_party/README.md index 458711607..171c54bd1 100644 --- a/packages/desktop/third_party/README.md +++ b/packages/desktop/third_party/README.md @@ -91,20 +91,25 @@ version, metadata, commit, and byte-hash gate used for FlatBuffers. ## PyObjC macOS runtime -- Distributions: `pyobjc-core==12.2.1` and - `pyobjc-framework-ApplicationServices==12.2.1` +- Distributions: `pyobjc-core` (`12.2.1` and `12.2.2`), + `pyobjc-framework-ApplicationServices==12.2.1`, + `pyobjc-framework-CoreMedia==12.2.2` and + `pyobjc-framework-ScreenCaptureKit==12.2.2` - Upstream repository: `https://github.com/ronaldoussoren/pyobjc` -- Upstream tag and commit: `v12.2.1`, - `cb525f3e7f433c851b68725dea54bc70d35681b8` -- Source paths: `pyobjc-core/License.txt` and - `pyobjc-framework-ApplicationServices/License.txt` +- Upstream tags and commits: `v12.2.1`, + `cb525f3e7f433c851b68725dea54bc70d35681b8`; `v12.2.2`, + `38cdf73fc049ef2d176973eff4ac8d5c76b0a34b` +- Source paths: `pyobjc-core/License.txt`, + `pyobjc-framework-ApplicationServices/License.txt`, + `pyobjc-framework-CoreMedia/License.txt` and + `pyobjc-framework-ScreenCaptureKit/License.txt` - Pinned license SHA-256: `0ca04b07928d4872b9d9bb22187ca0426dd8bfab08f26eada0999a71dc81aaff` - License: MIT -- Modification status: the two source files are byte-identical; copied without - modification as `pyobjc/LICENSE.txt` +- Modification status: the source files are byte-identical at both tags; + copied without modification as `pyobjc/LICENSE.txt` -The two applicable macOS wheels omit a concrete license file. The -frozen-runtime build supplies their shared exact upstream license only when -both package version and license metadata match the reviewed records. Symbol -files whose names merely contain `copying` are not treated as license notices. +These macOS wheels omit a concrete license file. The frozen-runtime build +supplies their shared exact upstream license only when both package version +and license metadata match the reviewed records. Symbol files whose names +merely contain `copying` are not treated as license notices. From 9de579ae42b61b32c26eeb07b8e3263ad95db434 Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 19 Oct 2026 18:30:06 -0400 Subject: [PATCH 3/6] fix(desktop): go back to tauri-plugin-deep-link 2.6.1 so the Linux shell compiles tauri-plugin-deep-link 2.6.2 builds rust-ini's ParseOption without the two fields rust-ini 0.21.3 added, so the Linux installer failed to compile (job 118267947408). #1324 took 2.6.2 with tauri-plugin-single-instance 2.5.4, which requires it. Both go back to the versions main built before (2.6.1 and 2.5.3). The Dependabot note now says to build the Linux installer before taking a plugin bump. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 2 ++ packages/desktop/src-tauri/Cargo.lock | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 62e2078c9..959797644 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -78,6 +78,8 @@ updates: update-types: ["minor", "patch"] ignore: # The Rust side of the Tauri pairs above; bumped with them, by hand. + # Build the Linux installer before taking a plugin bump: for example, + # tauri-plugin-deep-link 2.6.2 does not compile against rust-ini 0.21.3. - dependency-name: "tauri" - dependency-name: "tauri-*" - package-ecosystem: "github-actions" diff --git a/packages/desktop/src-tauri/Cargo.lock b/packages/desktop/src-tauri/Cargo.lock index 56ecbc222..81e738add 100644 --- a/packages/desktop/src-tauri/Cargo.lock +++ b/packages/desktop/src-tauri/Cargo.lock @@ -3941,9 +3941,9 @@ dependencies = [ [[package]] name = "tauri-plugin-deep-link" -version = "2.6.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b3c64e24ebcbc63aaa2d88a9c51e2507084b46620baf39ecb0baa0738a08bb4" +checksum = "4ac7a92a46ab5c88f44532ca50906d6e448a948d4ddf8c5376ab125e3260f736" dependencies = [ "dunce", "plist", @@ -4005,9 +4005,9 @@ dependencies = [ [[package]] name = "tauri-plugin-single-instance" -version = "2.5.4" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561cd99484561bc39c954768e7b41a66cebbe1ac3d9d081c34361f740c489e2c" +checksum = "3c142ed88deee222bd2d979269d35c73b6c1c0f6ebd5b79b4ff80066fcad6af1" dependencies = [ "serde", "serde_json", From a3cf8cbe259ca59595531fe320fa3e295799ba46 Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 19 Oct 2026 18:30:07 -0400 Subject: [PATCH 4/6] ci(desktop): pull requests run Windows engine tests and a macOS sidecar Three of main's desktop failures ran only on main, so no pull request could catch them. A pull request that touches Desktop now also runs: - the Python engine tests on Windows (Python 3.12); - the frozen sidecar build on macOS 14, where the PyObjC notices are checked; - the Linux installer, when it changes src-tauri/, package.json or package-lock.json. The native matrix is now built by the artifact-scope job, so a pull request can take only the Linux entry. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/desktop-build.yml | 71 ++++++++++--------- .github/workflows/desktop-test.yml | 10 +-- .../desktop/scripts/classify_build_changes.py | 19 ++++- .../tests/test_build_change_classifier.py | 9 +++ 4 files changed, 69 insertions(+), 40 deletions(-) diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index 640d536e4..6d4e5b044 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -24,6 +24,7 @@ jobs: outputs: run_sidecar: ${{ steps.scope.outputs.run_sidecar }} run_native: ${{ steps.scope.outputs.run_native }} + native_matrix: ${{ steps.scope.outputs.native_matrix }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -62,10 +63,36 @@ jobs: fi fi fi + if [ "${EVENT_NAME}" = "pull_request" ]; then + # The checkout is the merge commit; its first parent is the base. + git diff --relative --name-only HEAD^1 HEAD > "${changed_paths}" + fi python scripts/classify_build_changes.py \ --event "${EVENT_NAME}" \ --paths-file "${changed_paths}" \ --github-output "${GITHUB_OUTPUT}" + # A pull request builds the Linux installer only; main and dispatches + # build every platform. + python - "${EVENT_NAME}" >> "${GITHUB_OUTPUT}" <<'PY' + import json, sys + native = [ + {"label": "macOS arm64", "os": "macos-15", "platform": "macos", + "architecture": "arm64", "target": "aarch64-apple-darwin", + "bundles": "dmg", "signing": "adhoc"}, + {"label": "macOS Intel", "os": "macos-15-intel", "platform": "macos", + "architecture": "x86_64", "target": "x86_64-apple-darwin", + "bundles": "dmg", "signing": "adhoc"}, + {"label": "Windows x86_64", "os": "windows-2022", "platform": "windows", + "architecture": "x86_64", "target": "x86_64-pc-windows-msvc", + "bundles": "msi,nsis", "signing": "unsigned"}, + {"label": "Linux x86_64", "os": "ubuntu-22.04", "platform": "linux", + "architecture": "x86_64", "target": "x86_64-unknown-linux-gnu", + "bundles": "deb,appimage", "signing": "unsigned"}, + ] + if sys.argv[1] == "pull_request": + native = [entry for entry in native if entry["platform"] == "linux"] + print("native_matrix=" + json.dumps(native)) + PY frontend: name: Frontend behavior and build @@ -133,10 +160,11 @@ jobs: strategy: fail-fast: false matrix: - # PRs prove the frozen-engine contract once on Linux. Main repeats the - # complete matrix for dependency, toolchain, packaging, and native - # changes. Immutable native release tags rebuild every supported OS. - os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-22.04"]' || '["ubuntu-22.04", "macos-14", "windows-latest"]') }} + # PRs prove the frozen-engine contract on Linux and macOS (macOS freezes + # the PyObjC wheels, whose license notices the build must find). Main + # repeats the complete matrix for dependency, toolchain, packaging, and + # native changes. Immutable native release tags rebuild every supported OS. + os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-22.04", "macos-14"]' || '["ubuntu-22.04", "macos-14", "windows-latest"]') }} runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -182,7 +210,8 @@ jobs: name: Native installer (${{ matrix.label }}) needs: artifact-scope # Main runs this evidence for dependency, toolchain, packaging, and native - # changes. Application-only merges already pass the PR checks and the + # changes, and a pull request that changes the native shell builds the + # Linux installer. Application-only merges already pass the PR checks and the # exact-main frontend, distribution, and cross-platform test jobs. Every # immutable desktop-v* release tag rebuilds and tests all installers in the # separate Native Installer Release workflow. @@ -190,35 +219,9 @@ jobs: strategy: fail-fast: false matrix: - include: - - label: macOS arm64 - os: macos-15 - platform: macos - architecture: arm64 - target: aarch64-apple-darwin - bundles: dmg - signing: adhoc - - label: macOS Intel - os: macos-15-intel - platform: macos - architecture: x86_64 - target: x86_64-apple-darwin - bundles: dmg - signing: adhoc - - label: Windows x86_64 - os: windows-2022 - platform: windows - architecture: x86_64 - target: x86_64-pc-windows-msvc - bundles: msi,nsis - signing: unsigned - - label: Linux x86_64 - os: ubuntu-22.04 - platform: linux - architecture: x86_64 - target: x86_64-unknown-linux-gnu - bundles: deb,appimage - signing: unsigned + # Built by the artifact-scope job: every platform on main and dispatch, + # Linux only on a pull request that changes the native shell. + include: ${{ fromJSON(needs.artifact-scope.outputs.native_matrix) }} runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/desktop-test.yml b/.github/workflows/desktop-test.yml index d91bd7fc9..a79737e91 100644 --- a/.github/workflows/desktop-test.yml +++ b/.github/workflows/desktop-test.yml @@ -2,9 +2,10 @@ # # Called from packages.yml when a change touches packages/desktop, so its jobs # feed the required packages-gate. Pull requests run the Linux lane on Python -# 3.11 and 3.12. A push to main repeats the same contract on macOS and Windows, -# so a release always rests on the complete cross-platform matrix. Ported from -# openadapt-desktop's test.yml. +# 3.11 and 3.12 and one Windows lane, because Windows checks files out with CRLF +# and has its own paths. A push to main repeats the same contract on macOS and +# Windows, so a release always rests on the complete cross-platform matrix. +# Ported from openadapt-desktop's test.yml. name: Desktop test on: @@ -23,8 +24,9 @@ jobs: strategy: fail-fast: false matrix: - os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-latest"]' || '["ubuntu-latest", "macos-latest", "windows-latest"]') }} + os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-latest", "windows-latest"]' || '["ubuntu-latest", "macos-latest", "windows-latest"]') }} python-version: ["3.11", "3.12"] + exclude: ${{ fromJSON(github.event_name == 'pull_request' && '[{"os":"windows-latest","python-version":"3.11"}]' || '[]') }} runs-on: ${{ matrix.os }} timeout-minutes: 45 steps: diff --git a/packages/desktop/scripts/classify_build_changes.py b/packages/desktop/scripts/classify_build_changes.py index ec27f69e3..2c41eb576 100644 --- a/packages/desktop/scripts/classify_build_changes.py +++ b/packages/desktop/scripts/classify_build_changes.py @@ -1,6 +1,8 @@ """Classify whether a Desktop change needs full native artifact builds. -Pull requests keep the representative Linux frozen-sidecar build. Release +Pull requests keep the representative frozen-sidecar builds, and a pull +request that changes the Tauri shell or its JavaScript locks also builds the +Linux installer, so a native dependency bump compiles before it merges. Release candidates and explicit dispatches keep the complete platform matrix. A push to protected ``main`` repeats the expensive matrix only when a dependency, toolchain, packaging, or native-runtime input changed. The immutable native @@ -51,6 +53,12 @@ "scripts/verify_build_artifact.py", } +# A pull request that changes one of these also builds the Linux installer. +# The Rust shell and its plugins compile per platform, and the npm and cargo +# sides of each Tauri plugin must move together. +NATIVE_PR_FILES = {"package-lock.json", "package.json"} +NATIVE_PR_PREFIXES = ("src-tauri/",) + # These paths get the normal PR checks and the exact-main frontend, Python # distribution, and cross-platform test jobs. They do not change the native # packaging contract. Everything not named here fails toward the full matrix. @@ -105,12 +113,19 @@ def classify_build_scope(event: str, changed_paths: Iterable[str]) -> BuildScope if event == "workflow_dispatch": return BuildScope(True, True, "explicit release-candidate build") + paths = tuple(path for raw in changed_paths if (path := _normalize(raw))) if event == "pull_request": + native = tuple( + path + for path in paths + if path in NATIVE_PR_FILES or path.startswith(NATIVE_PR_PREFIXES) + ) + if native: + return BuildScope(True, True, f"pull request changes the native shell: {native[0]}") return BuildScope(True, False, "representative pull-request sidecar") if event != "push": return BuildScope(True, True, f"unknown event {event!r}; fail toward full evidence") - paths = tuple(path for raw in changed_paths if (path := _normalize(raw))) if not paths: return BuildScope(True, True, "no changed paths; fail toward full evidence") diff --git a/packages/desktop/tests/test_build_change_classifier.py b/packages/desktop/tests/test_build_change_classifier.py index 51e5df0e4..8e87ddd4b 100644 --- a/packages/desktop/tests/test_build_change_classifier.py +++ b/packages/desktop/tests/test_build_change_classifier.py @@ -13,6 +13,15 @@ def test_pull_request_keeps_one_representative_sidecar() -> None: ) +@pytest.mark.parametrize( + "path", ["src-tauri/Cargo.lock", "src-tauri/src/main.rs", "package.json", "package-lock.json"] +) +def test_pull_request_that_changes_the_native_shell_builds_an_installer(path: str) -> None: + scope = classify_build_scope("pull_request", ["src/App.tsx", path]) + assert scope.run_sidecar and scope.run_native + assert path in scope.reason + + def test_explicit_release_candidate_keeps_the_complete_matrix() -> None: assert classify_build_scope("workflow_dispatch", []) == BuildScope( run_sidecar=True, From bc119de6bc0102d703432fa1f342d51aa9cfcbe6 Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 19 Oct 2026 18:30:17 -0400 Subject: [PATCH 5/6] chore: release 0.21.1 Co-Authored-By: Claude Opus 5.5 --- packages/desktop/CHANGELOG.md | 12 ++++++++++++ packages/desktop/openadapt_desktop/__init__.py | 2 +- packages/desktop/package-lock.json | 4 ++-- packages/desktop/package.json | 2 +- packages/desktop/pyproject.toml | 2 +- packages/desktop/src-tauri/Cargo.lock | 2 +- packages/desktop/src-tauri/Cargo.toml | 2 +- packages/desktop/src-tauri/tauri.conf.json | 2 +- packages/desktop/uv.lock | 2 +- 9 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/desktop/CHANGELOG.md b/packages/desktop/CHANGELOG.md index 9ebd38c1c..c6851892c 100644 --- a/packages/desktop/CHANGELOG.md +++ b/packages/desktop/CHANGELOG.md @@ -1,6 +1,18 @@ # CHANGELOG +## v0.21.1 (2026-10-19) + +0.21.0 was never published, because main's macOS, Windows and Linux builds of it failed. This release ships the 0.21.0 changes below together with these fixes. + +### Bug Fixes + +- **desktop**: go back to tauri-plugin-deep-link 2.6.1 so the Linux shell compiles +- **desktop**: supply the reviewed PyObjC license for the 12.2.2 wheels +- **desktop**: prepare a release on a CRLF checkout + + + ## v0.21.0 (2026-10-18) ### Features diff --git a/packages/desktop/openadapt_desktop/__init__.py b/packages/desktop/openadapt_desktop/__init__.py index 601b30681..bd0497bcd 100644 --- a/packages/desktop/openadapt_desktop/__init__.py +++ b/packages/desktop/openadapt_desktop/__init__.py @@ -21,4 +21,4 @@ +-- backends/ Storage backend plugins """ -__version__ = "0.21.0" +__version__ = "0.21.1" diff --git a/packages/desktop/package-lock.json b/packages/desktop/package-lock.json index a35042ee8..6a0a57428 100644 --- a/packages/desktop/package-lock.json +++ b/packages/desktop/package-lock.json @@ -1,12 +1,12 @@ { "name": "openadapt-desktop", - "version": "0.21.0", + "version": "0.21.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openadapt-desktop", - "version": "0.21.0", + "version": "0.21.1", "dependencies": { "@tauri-apps/api": "^2", "@tauri-apps/plugin-notification": "^2", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index bd94fc447..32a33a5d7 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "openadapt-desktop", - "version": "0.21.0", + "version": "0.21.1", "description": "Installed companion for OpenAdapt authoring, teaching, and local pairing", "private": true, "type": "module", diff --git a/packages/desktop/pyproject.toml b/packages/desktop/pyproject.toml index 29faee9cc..e06f4b378 100644 --- a/packages/desktop/pyproject.toml +++ b/packages/desktop/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "openadapt-desktop" -version = "0.21.0" +version = "0.21.1" description = "The OpenAdapt desktop app and local engine: record a data-entry task, run it on a list, and check each saved record" readme = "README.md" requires-python = ">=3.11" diff --git a/packages/desktop/src-tauri/Cargo.lock b/packages/desktop/src-tauri/Cargo.lock index 81e738add..b7e27df90 100644 --- a/packages/desktop/src-tauri/Cargo.lock +++ b/packages/desktop/src-tauri/Cargo.lock @@ -2502,7 +2502,7 @@ dependencies = [ [[package]] name = "openadapt-desktop" -version = "0.21.0" +version = "0.21.1" dependencies = [ "hex", "reqwest", diff --git a/packages/desktop/src-tauri/Cargo.toml b/packages/desktop/src-tauri/Cargo.toml index 7b1dcd390..fe9612c3c 100644 --- a/packages/desktop/src-tauri/Cargo.toml +++ b/packages/desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openadapt-desktop" -version = "0.21.0" +version = "0.21.1" description = "Installed companion for OpenAdapt authoring, teaching, and local pairing" authors = ["OpenAdapt AI"] license = "MIT" diff --git a/packages/desktop/src-tauri/tauri.conf.json b/packages/desktop/src-tauri/tauri.conf.json index aea2772db..fad2fc57b 100644 --- a/packages/desktop/src-tauri/tauri.conf.json +++ b/packages/desktop/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/nicoverbruggen/tauri-v2-schema/main/schema.json", "productName": "OpenAdapt Desktop", - "version": "0.21.0", + "version": "0.21.1", "identifier": "ai.openadapt.desktop", "build": { "frontendDist": "../dist", diff --git a/packages/desktop/uv.lock b/packages/desktop/uv.lock index 307424ab4..61e69db20 100644 --- a/packages/desktop/uv.lock +++ b/packages/desktop/uv.lock @@ -1159,7 +1159,7 @@ wheels = [ [[package]] name = "openadapt-desktop" -version = "0.21.0" +version = "0.21.1" source = { editable = "." } dependencies = [ { name = "cryptography" }, From c95e6f01bc69f85bfee9035e01542cac61b678b4 Mon Sep 17 00:00:00 2001 From: abrichr Date: Mon, 19 Oct 2026 19:00:27 -0400 Subject: [PATCH 6/6] test(desktop): the CRLF test commits even when Windows already checked out CRLF Co-Authored-By: Claude Opus 5.5 --- packages/desktop/tests/test_release_intent.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/desktop/tests/test_release_intent.py b/packages/desktop/tests/test_release_intent.py index 7d65b34c6..79c79022c 100644 --- a/packages/desktop/tests/test_release_intent.py +++ b/packages/desktop/tests/test_release_intent.py @@ -125,7 +125,10 @@ def test_prepare_works_on_a_crlf_checkout(repo: Path) -> None: for relative in VERSION_FILES: path = repo / relative path.write_bytes(path.read_bytes().replace(b"\r\n", b"\n").replace(b"\n", b"\r\n")) - _commit(repo, "chore: check out with CRLF") + # On Windows the checkout (and so the fixture) is already CRLF, so the + # rewrite can leave nothing to commit; the test is the prepare() below. + _git(repo, "add", "-A") + _git(repo, "commit", "-q", "--allow-empty", "-m", "chore: check out with CRLF") _commit(repo, "fix(portal): keep the card", touch="src/portal.txt") version = prepare_release.prepare(repo, today=datetime.date(2026, 10, 19))