feat: add interactive settings editor TUI with keyboard navigation, l… #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release Desktop DMG | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "pyproject.toml" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| release-dmg: | |
| runs-on: macos-14 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Read package version | |
| id: version | |
| env: | |
| BEFORE_SHA: ${{ github.event.before || '' }} | |
| run: | | |
| current_version="$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')" | |
| version_changed="true" | |
| if [ "$GITHUB_EVENT_NAME" = "push" ] && [ -n "$BEFORE_SHA" ] && git cat-file -e "${BEFORE_SHA}:pyproject.toml" 2>/dev/null; then | |
| previous_version="$(git show "${BEFORE_SHA}:pyproject.toml" | python3 -c 'import sys, tomllib; print(tomllib.loads(sys.stdin.read())["project"]["version"])')" | |
| if [ "$current_version" = "$previous_version" ]; then | |
| version_changed="false" | |
| fi | |
| echo "Previous package version: $previous_version" | |
| fi | |
| echo "Current package version: $current_version" | |
| echo "Package version changed: $version_changed" | |
| { | |
| echo "version=$current_version" | |
| echo "tag=v$current_version" | |
| echo "should_build=$version_changed" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Wait for matching GitHub Release | |
| id: release | |
| if: steps.version.outputs.should_build == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.version.outputs.tag }} | |
| run: | | |
| for attempt in $(seq 1 60); do | |
| if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then | |
| echo "Found release $RELEASE_TAG" | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Waiting for release $RELEASE_TAG ($attempt/60)" | |
| sleep 20 | |
| done | |
| echo "Release $RELEASE_TAG was not found; skipping desktop DMG upload." | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| - name: Set up Python | |
| if: steps.release.outputs.exists == 'true' | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Set up uv | |
| if: steps.release.outputs.exists == 'true' | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| enable-cache: true | |
| - name: Set up Node.js | |
| if: steps.release.outputs.exists == 'true' | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| cache: npm | |
| - name: Set up Rust | |
| if: steps.release.outputs.exists == 'true' | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install frontend dependencies | |
| if: steps.release.outputs.exists == 'true' | |
| run: npm ci | |
| - name: Sync Python environment | |
| if: steps.release.outputs.exists == 'true' | |
| run: uv sync | |
| - name: Set desktop bundle version | |
| if: steps.release.outputs.exists == 'true' | |
| env: | |
| DESKTOP_RELEASE_VERSION: ${{ steps.version.outputs.version }} | |
| run: | | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| import re | |
| from pathlib import Path | |
| version = os.environ["DESKTOP_RELEASE_VERSION"] | |
| tauri_config_path = Path("src-tauri/tauri.conf.json") | |
| tauri_config = json.loads(tauri_config_path.read_text(encoding="utf-8")) | |
| tauri_config["version"] = version | |
| tauri_config_path.write_text( | |
| json.dumps(tauri_config, indent=2) + "\n", | |
| encoding="utf-8", | |
| ) | |
| cargo_toml_path = Path("src-tauri/Cargo.toml") | |
| cargo_toml = cargo_toml_path.read_text(encoding="utf-8") | |
| cargo_toml = re.sub( | |
| r'(?m)^version = "[^"]+"', | |
| f'version = "{version}"', | |
| cargo_toml, | |
| count=1, | |
| ) | |
| cargo_toml_path.write_text(cargo_toml, encoding="utf-8") | |
| PY | |
| - name: Build desktop DMG | |
| if: steps.release.outputs.exists == 'true' | |
| run: npm run tauri:build | |
| - name: Locate DMG | |
| id: dmg | |
| if: steps.release.outputs.exists == 'true' | |
| run: | | |
| dmg_path="$(find src-tauri/target/release/bundle/dmg -maxdepth 1 -type f -name '*.dmg' | sort | tail -n 1)" | |
| if [ -z "$dmg_path" ]; then | |
| echo "No DMG produced by Tauri build." >&2 | |
| exit 1 | |
| fi | |
| echo "DMG: $dmg_path" | |
| { | |
| echo "path<<EOF" | |
| echo "$dmg_path" | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Upload DMG to GitHub Release | |
| if: steps.release.outputs.exists == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ steps.version.outputs.tag }} | |
| DMG_PATH: ${{ steps.dmg.outputs.path }} | |
| run: gh release upload "$RELEASE_TAG" "$DMG_PATH" --clobber |