Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: macOS release

on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
apple-silicon-dmg:
runs-on: macos-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm

- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin

- run: npm ci

- name: Build and publish DMG
uses: tauri-apps/tauri-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: ${{ github.ref_name }}
releaseName: Touch Manager ${{ github.ref_name }}
releaseBody: |
Apple Silicon development preview.

This build is not Apple-notarized. On first launch, Control-click Touch Manager and choose Open. Install dfu-util separately with Homebrew before flashing hardware.
prerelease: true
args: --target aarch64-apple-darwin --bundles dmg
releaseAssetNamePattern: Touch-Manager_[version]_[arch].[ext]
uploadUpdaterSignatures: false
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ BOOT/RESET recovery path.
The full architecture, threat model, target profiles, TouchLink proposal, and phased
roadmap are in [BUILD_PLAN.md](BUILD_PLAN.md).

## Download

Download the latest macOS installer from
[GitHub Releases](https://github.com/alibros/touch-manager/releases).

The current preview is built for Apple Silicon Macs. It is ad-hoc signed rather than
Apple-notarized, so first launch may require Control-clicking the app, choosing **Open**,
or approving it in **System Settings → Privacy & Security**. Install `dfu-util` with
`brew install dfu-util` before writing firmware.

Release builds contain the firmware catalog but do not redistribute upstream firmware
binaries. Users can import a `.bin` directly or provide the Synthux firmware workspace
described below.

## Safety model

The frontend cannot supply a shell command, arbitrary address, or DFU alternate setting.
Expand Down Expand Up @@ -71,9 +85,9 @@ Resolution order:

1. `SYNTHUX_WORKSPACE`
2. An ancestor of the current working directory
3. `~/dev/synthux` for Finder-launched local macOS builds

For a custom checkout location:
For a custom checkout location, set the workspace explicitly when starting the development
build:

```sh
export SYNTHUX_WORKSPACE=/absolute/path/to/synthux
Expand Down Expand Up @@ -101,9 +115,10 @@ without requiring or redistributing those binaries.
npm run tauri -- build
```

Local macOS bundles are development artifacts. Public downloads must be signed with an
Apple Developer ID and notarized. Windows releases need explicit WinUSB guidance, and
Linux releases need narrow udev rules; those distribution tasks remain on the roadmap.
Current macOS downloads are clearly labelled development previews. A polished stable
release still requires Apple Developer ID signing and notarization. Windows releases need
explicit WinUSB guidance, and Linux releases need narrow udev rules; those distribution
tasks remain on the roadmap.

## Buttonless updates

Expand Down
14 changes: 2 additions & 12 deletions src-tauri/src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,11 @@ fn discover_workspace_root() -> Option<PathBuf> {
}
}

let from_current_directory = env::current_dir().ok().and_then(|cwd| {
env::current_dir().ok().and_then(|cwd| {
cwd.ancestors()
.find(|candidate| candidate.join("Firmware/SHA256SUMS.txt").is_file())
.map(PathBuf::from)
});
if from_current_directory.is_some() {
return from_current_directory;
}

// Finder-launched macOS applications do not inherit the terminal's working
// directory. Keep the source workspace discoverable for local installations.
env::var_os("HOME")
.map(PathBuf::from)
.map(|home| home.join("dev/synthux"))
.filter(|candidate| candidate.join("Firmware/SHA256SUMS.txt").is_file())
})
}

#[allow(dead_code)]
Expand Down