From 2b7247c94818438701ca20e3252febc48b2b0bfa Mon Sep 17 00:00:00 2001 From: Kiruno-lz Date: Thu, 7 May 2026 18:42:26 +0800 Subject: [PATCH] [feature] Add brew cask install option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Casks/openless.rb 添加相关README说明 修改github ci支持发布版本自动更新Casks/openless.rb --- .github/workflows/update-cask.yml | 83 +++++++++++++++++++++++++++++++ Casks/openless.rb | 29 +++++++++++ Formula/openless.rb | 67 +++++++++++++++++++++++++ README.md | 9 ++++ README.zh.md | 11 +++- 5 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/update-cask.yml create mode 100644 Casks/openless.rb create mode 100644 Formula/openless.rb diff --git a/.github/workflows/update-cask.yml b/.github/workflows/update-cask.yml new file mode 100644 index 00000000..feea2912 --- /dev/null +++ b/.github/workflows/update-cask.yml @@ -0,0 +1,83 @@ +name: Update Cask on Release + +on: + release: + types: [published] + +jobs: + update-cask: + runs-on: ubuntu-latest + permissions: + contents: write + if: startsWith(github.event.release.tag_name, 'v') && endsWith(github.event.release.tag_name, '-tauri') + steps: + - name: Checkout tap repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract version from tag + id: version + run: | + TAG="${{ github.event.release.tag_name }}" + VERSION="${TAG#v}" + VERSION="${VERSION%-tauri}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Detected version: $VERSION" + + - name: Fetch release assets SHA256 + id: sha256 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + VERSION="${{ steps.version.outputs.version }}" + REPO="${{ github.repository }}" + + # Fetch release assets info + RESPONSE=$(gh api "repos/$REPO/releases/tags/v${VERSION}-tauri") + + # Extract SHA256 for aarch64 DMG + ARM64_SHA=$(echo "$RESPONSE" | jq -r '.assets[] | select(.name | contains("aarch64.dmg")) | .digest' | sed 's/sha256://') + + # Extract SHA256 for x64 DMG + X64_SHA=$(echo "$RESPONSE" | jq -r '.assets[] | select(.name | contains("_x64.dmg")) | .digest' | sed 's/sha256://') + + echo "arm64_sha=$ARM64_SHA" >> "$GITHUB_OUTPUT" + echo "x64_sha=$X64_SHA" >> "$GITHUB_OUTPUT" + + echo "aarch64 DMG SHA256: $ARM64_SHA" + echo "x64 DMG SHA256: $X64_SHA" + + - name: Update Cask file + run: | + VERSION="${{ steps.version.outputs.version }}" + ARM64_SHA="${{ steps.sha256.outputs.arm64_sha }}" + X64_SHA="${{ steps.sha256.outputs.x64_sha }}" + CASK_FILE="Casks/openless.rb" + + # Update version + sed -i "s/version \"[^\"]*\"/version \"$VERSION\"/" "$CASK_FILE" + + # Update SHA256 values + sed -i "s/sha256 arm: \"[^\"]*\"/sha256 arm: \"$ARM64_SHA\"/" "$CASK_FILE" + sed -i "s/intel: \"[^\"]*\"/intel: \"$X64_SHA\"/" "$CASK_FILE" + + echo "Updated $CASK_FILE:" + cat "$CASK_FILE" + + - name: Commit and push changes + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + + VERSION="${{ steps.version.outputs.version }}" + + git add Casks/openless.rb + + if git diff --cached --quiet; then + echo "No changes to commit" + exit 0 + fi + + git commit -m "[cask] Update openless to $VERSION" + git push diff --git a/Casks/openless.rb b/Casks/openless.rb new file mode 100644 index 00000000..60a88dc6 --- /dev/null +++ b/Casks/openless.rb @@ -0,0 +1,29 @@ +cask "openless" do + arch arm: "aarch64", intel: "x64" + + version "1.2.22" + sha256 arm: "8e65729eb671f5fec3ce392d4f8dfd33303f1c84f8f4533683f8d3a3afd1e21d", + intel: "6d97fb7cab173b4f3241aa18b3db0f51a03a03d6b2bdea48cab8fe761440df7b" + + url "https://github.com/appergb/openless/releases/download/v#{version}-tauri/OpenLess_#{version}_#{arch}.dmg" + name "OpenLess" + desc "Menu-bar voice input layer for macOS" + homepage "https://github.com/appergb/openless" + + livecheck do + url :url + regex(/^v?(\d+(?:\.\d+)+)[._-]tauri$/i) + end + + auto_updates true + + app "OpenLess.app" + + zap trash: [ + "~/Library/Application Support/OpenLess", + "~/Library/Caches/com.openless.app", + "~/Library/Logs/OpenLess", + "~/Library/Preferences/com.openless.app.plist", + "~/Library/WebKit/com.openless.app", + ] +end diff --git a/Formula/openless.rb b/Formula/openless.rb new file mode 100644 index 00000000..bfc1bf46 --- /dev/null +++ b/Formula/openless.rb @@ -0,0 +1,67 @@ +class Openless < Formula + desc "Menu-bar voice input layer for macOS" + homepage "https://github.com/appergb/openless" + url "https://github.com/appergb/openless/archive/refs/tags/v1.2.20-tauri.tar.gz" + sha256 "be1363f7762a42b7e932ec3cc687cfdfb5b550b6cf1c96d52a1f87c906f27863" + license "MIT" + + head "https://github.com/appergb/openless.git", branch: "main" + + depends_on "rust" => :build + depends_on "node" => :build + depends_on :macos + depends_on arch: :arm64 + + # qwen-asr submodule for local ASR engine on macOS + resource "qwen-asr" do + url "https://github.com/antirez/qwen-asr.git", + revision: "b00b789b17051aea61e9717458171100662318a4" + end + + def install + # Place submodule at expected path before building + vendor_dir = "openless-all/app/src-tauri/vendor/qwen-asr" + rm_rf vendor_dir + resource("qwen-asr").stage(vendor_dir) + + cd "openless-all/app" do + # Install frontend dependencies + system "npm", "ci" + + # Build Tauri app with ad-hoc signing (no Developer ID required) + ENV["APPLE_SIGNING_IDENTITY"] = "-" + system "npm", "run", "tauri", "--", "build" + + # Install the .app bundle + prefix.install "src-tauri/target/release/bundle/macos/OpenLess.app" + end + + # Symlink binary for command-line access + bin.install_symlink prefix/"OpenLess.app/Contents/MacOS/openless" + end + + def caveats + <<~EOS + OpenLess.app has been installed to: + #{prefix}/OpenLess.app + + To use it, link it into /Applications: + ln -sf #{opt_prefix}/OpenLess.app /Applications/OpenLess.app + + Or launch it directly: + open #{opt_prefix}/OpenLess.app + + First-time setup: + - Grant Accessibility permission when prompted + - Grant Microphone permission when prompted + + If Gatekeeper blocks the app (ad-hoc signed), run: + xattr -cr /Applications/OpenLess.app + EOS + end + + test do + assert_path_exists prefix/"OpenLess.app" + assert_predicate prefix/"OpenLess.app/Contents/MacOS/openless", :executable? + end +end diff --git a/README.md b/README.md index 182a1838..b37b53b4 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,15 @@ OpenLess does one thing: **turn speech into usable written text (especially AI p Go to [Releases](../../releases) and download: - **macOS**: `OpenLess__aarch64.dmg` — open, drag to `/Applications` - **Windows**: `OpenLess__x64-setup.exe` — run the installer +- **macOS(brew install)**: +```bash +brew tap appergb/openless https://github.com/appergb/openless +brew install --cask openless +xattr -cr /Applications/OpenLess.app + +# Upgrade to the latest version +brew update && brew upgrade openless +``` On first launch, grant the permissions the app requests: diff --git a/README.zh.md b/README.zh.md index d3cb93de..40d0eb61 100644 --- a/README.zh.md +++ b/README.zh.md @@ -146,8 +146,17 @@ OpenLess 只做一件事:**把语音变成可用的书面文字(尤其是 AI ## 下载与安装(普通用户) 到 [Releases](../../releases) 下载对应平台的安装包: -- **macOS**:`OpenLess_<版本>_aarch64.dmg` — 打开后拖入「应用程序」 - **Windows**:`OpenLess_<版本>_x64-setup.exe` — 运行安装程序 +- **macOS**:`OpenLess_<版本>_aarch64.dmg` — 打开后拖入「应用程序」 +- **macOS(brew install)**: +```bash +brew tap appergb/openless https://github.com/appergb/openless +brew install --cask openless +xattr -cr /Applications/OpenLess.app + +# Upgrade to the latest version +brew update && brew upgrade openless +``` 首次启动需要授予权限: