codeburn/.github/workflows/release-desktop-linux.yml
Resham Joshi 8590087392 feat(desktop): scaffold Tauri 2.x tray app for Linux + Windows
Adds desktop/ with a native tray app that mirrors the macOS popover via
a shared tokens.json and the same codeburn status --format menubar-json
data source. Same security posture as the Swift app: argv-validated CLI
spawn, O_NOFOLLOW cache writes, flock on config.json, FX rate clamping
to [0.0001, 1_000_000].

Stack:
- Tauri 2.x (Rust) for tray + window lifecycle, shells out to the CLI
- React + TypeScript + Vite for the popover UI
- libayatana-appindicator on Linux, system tray on Windows
- Produces .deb / .rpm / .AppImage on ubuntu-latest, .msi on
  windows-latest. Both workflows run on free GitHub Actions minutes.

Rust modules (src-tauri/src/):
- lib.rs:    tray icon, menu events, popover toggle, state wiring
- cli.rs:    CodeburnCli with argv allowlist and bounded pipe drain
             (20 MB stdout / 256 KB stderr / 60 s wall time)
- config.rs: flock-guarded read-modify-write of ~/.config/codeburn/config.json
- fx.rs:     Frankfurter fetch with 24 h disk cache, bounds check

Frontend:
- App.tsx with agent tabs, period switcher, hero cost, activity rows,
  optimize findings CTA, footer (currency picker / refresh / Open
  Full Report). Listens for `codeburn://refresh` tray events.
- lib/payload.ts mirrors the CLI's MenubarPayload shape
- lib/currency.ts mirrors the Swift Double.asCurrency helpers
- styles.css with design tokens as CSS custom properties

CLI:
- `codeburn menubar` now platform-dispatches: macOS (.app zip),
  Linux (.AppImage into ~/.local/bin), Windows (.msi via msiexec).
  macOS behaviour preserved exactly.

Release workflow:
- .github/workflows/release-desktop-linux.yml triggers on `linux-v*`
  tags, builds all three Linux formats, uploads to GitHub Releases.

Scaffold verified:
- cargo check -> clean
- tsc --noEmit -> clean
- npm run build (CLI) -> 205 KB
- Existing test suite: 230 / 230 still pass
2026-04-17 17:53:10 -07:00

109 lines
3.4 KiB
YAML

name: Release Linux Desktop
# Triggers on a `linux-v*` tag push (e.g. `git tag linux-v0.1.0 && git push origin linux-v0.1.0`),
# or manually via the Actions tab. Runs on the free ubuntu-latest runner. No signing cert
# required; AppImages don't use OS-level code signing and users trust the download by SHA.
on:
push:
tags:
- 'linux-v*'
workflow_dispatch:
inputs:
version:
description: 'Version label for the bundle (e.g. v0.1.0 or dev-preview)'
required: true
default: 'dev-preview'
permissions:
contents: write # Needed to create the release + upload assets.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Resolve version label
id: version
run: |
if [[ "${GITHUB_REF}" == refs/tags/linux-v* ]]; then
echo "value=${GITHUB_REF#refs/tags/linux-}" >> "$GITHUB_OUTPUT"
else
echo "value=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT"
fi
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libssl-dev \
libxdo-dev \
libgtk-3-dev \
build-essential
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
desktop/src-tauri/target
key: ${{ runner.os }}-cargo-${{ hashFiles('desktop/src-tauri/Cargo.lock') }}
- name: Install npm deps
working-directory: desktop
run: npm install
- name: Build bundles
working-directory: desktop
# Produces .deb, .rpm, and .AppImage under src-tauri/target/release/bundle/
run: npm run tauri build
- name: Collect artifacts
id: collect
run: |
mkdir -p release-artifacts
find desktop/src-tauri/target/release/bundle -type f \
\( -name '*.deb' -o -name '*.rpm' -o -name '*.AppImage' \) \
-exec cp -v {} release-artifacts/ \;
ls -la release-artifacts
- name: Upload artifact (manual runs)
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: codeburn-desktop-linux-${{ steps.version.outputs.value }}
path: release-artifacts/*
if-no-files-found: error
- name: Create / update GitHub Release
if: startsWith(github.ref, 'refs/tags/linux-v')
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: Linux Desktop ${{ steps.version.outputs.value }}
body: |
Install with:
```
npx codeburn menubar
```
That command grabs the right asset for your architecture (x86_64 or aarch64)
and installs it to `~/.local/bin`. Prefer a distro package? Download the `.deb`
or `.rpm` below and install with `sudo apt install ./file.deb` or
`sudo rpm -i file.rpm`.
files: release-artifacts/*
fail_on_unmatched_files: true