Skip to content

Commit e4fe2b5

Browse files
committed
v0.4.0: add cross-platform desktop UI (egui)
New bin 'mhrv-rs-ui' behind the 'ui' feature flag. CLI users pay zero egui compile cost; UI users get a single static binary. UI features: - Config form (Apps Script ID, auth key, Google IP, front domain, ports, log level, verify_ssl) - Start/Stop buttons that spawn the proxy on a dedicated tokio thread - Live stats (relay calls, failures, cache hit rate, bytes relayed, blacklisted scripts) polled every ~700ms - Test button (end-to-end relay probe) - Install CA / Check CA buttons - Recent log panel (last 200 lines) - Dense, dark, utility-look: no emojis, no cards, no gradients Architecture: - Refactored crate into lib + two bins (mhrv-rs, mhrv-rs-ui). src/lib.rs exposes all modules, main.rs uses them via 'use mhrv_rs::...' - New src/data_dir.rs: platform-appropriate user data dir (~/Library/Application Support/mhrv-rs on macOS, ~/.config/mhrv-rs on Linux, %APPDATA%\mhrv-rs on Windows). CLI falls back to ./config.json for backward compat. - CA moves to {data_dir}/ca/ca.crt (was ./ca/ca.crt). - UI background thread owns the tokio runtime and proxy handle; communicates with UI via std::mpsc commands + Arc<Mutex<UiState>>. - macOS .app bundle: assets/macos/Info.plist template + build-app.sh that assembles .app from the binary. Bundled into release zips. - CI: Linux system libs (libxkbcommon, libwayland, libxcb*, libx11, libgl, libgtk-3) installed on Ubuntu runners for eframe. aarch64 Linux UI is best-effort cross-compile. Windows MinGW, macOS native. 25 lib tests still pass. 5MB release UI binary on macOS.
1 parent c694073 commit e4fe2b5

10 files changed

Lines changed: 3452 additions & 248 deletions

File tree

.github/workflows/release.yml

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ permissions:
1111
jobs:
1212
build:
1313
strategy:
14+
fail-fast: false
1415
matrix:
1516
include:
1617
- target: x86_64-unknown-linux-gnu
@@ -38,7 +39,40 @@ jobs:
3839
with:
3940
targets: ${{ matrix.target }}
4041

41-
- name: Install MinGW toolchain
42+
# eframe needs a few system libs on Linux for window management, keyboard,
43+
# and OpenGL/X11/Wayland. We install them on the Ubuntu runners regardless
44+
# of arch so both CLI-only and UI builds succeed.
45+
- name: Install Linux eframe system deps
46+
if: runner.os == 'Linux'
47+
run: |
48+
sudo apt-get update
49+
sudo apt-get install -y \
50+
libxkbcommon-dev \
51+
libwayland-dev \
52+
libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
53+
libx11-dev \
54+
libgl1-mesa-dev libglib2.0-dev libgtk-3-dev
55+
56+
- name: Install aarch64 cross-compile toolchain (Linux only)
57+
if: matrix.target == 'aarch64-unknown-linux-gnu'
58+
run: |
59+
sudo dpkg --add-architecture arm64
60+
sudo sed -i 's#^deb http#deb [arch=amd64] http#' /etc/apt/sources.list || true
61+
echo 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted universe multiverse' | sudo tee /etc/apt/sources.list.d/arm64.list
62+
echo 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted universe multiverse' | sudo tee -a /etc/apt/sources.list.d/arm64.list
63+
sudo apt-get update
64+
sudo apt-get install -y gcc-aarch64-linux-gnu \
65+
libxkbcommon-dev:arm64 \
66+
libwayland-dev:arm64 \
67+
libxcb1-dev:arm64 libxcb-render0-dev:arm64 libxcb-shape0-dev:arm64 libxcb-xfixes0-dev:arm64 \
68+
libx11-dev:arm64 \
69+
libgl1-mesa-dev:arm64 libglib2.0-dev:arm64 libgtk-3-dev:arm64 || true
70+
echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config.toml
71+
echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config.toml
72+
echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig" >> $GITHUB_ENV
73+
echo "PKG_CONFIG_ALLOW_CROSS=1" >> $GITHUB_ENV
74+
75+
- name: Install Windows MinGW toolchain
4276
if: matrix.target == 'x86_64-pc-windows-gnu'
4377
id: msys2
4478
uses: msys2/setup-msys2@v2
@@ -47,15 +81,7 @@ jobs:
4781
update: true
4882
install: mingw-w64-x86_64-gcc
4983

50-
- name: Install cross-compilation tools
51-
if: matrix.target == 'aarch64-unknown-linux-gnu'
52-
run: |
53-
sudo apt-get update
54-
sudo apt-get install -y gcc-aarch64-linux-gnu
55-
echo '[target.aarch64-unknown-linux-gnu]' >> ~/.cargo/config.toml
56-
echo 'linker = "aarch64-linux-gnu-gcc"' >> ~/.cargo/config.toml
57-
58-
- name: Configure GNU linker
84+
- name: Configure Windows GNU linker
5985
if: matrix.target == 'x86_64-pc-windows-gnu'
6086
shell: pwsh
6187
run: |
@@ -64,27 +90,69 @@ jobs:
6490
Add-Content -Path $env:USERPROFILE/.cargo/config.toml -Value '[target.x86_64-pc-windows-gnu]'
6591
Add-Content -Path $env:USERPROFILE/.cargo/config.toml -Value "linker = '$gcc'"
6692
67-
- name: Build
68-
run: cargo build --release --target ${{ matrix.target }}
93+
- name: Build CLI
94+
run: cargo build --release --target ${{ matrix.target }} --bin mhrv-rs
95+
96+
# UI build: we try to build the UI binary on every platform. If it fails
97+
# on cross-compile for linux-arm64 (missing arm64 system libs cross),
98+
# we still ship the CLI.
99+
- name: Build UI
100+
if: matrix.target != 'aarch64-unknown-linux-gnu'
101+
run: cargo build --release --target ${{ matrix.target }} --features ui --bin mhrv-rs-ui
102+
103+
- name: Try UI on aarch64-linux (best effort)
104+
if: matrix.target == 'aarch64-unknown-linux-gnu'
105+
continue-on-error: true
106+
run: cargo build --release --target ${{ matrix.target }} --features ui --bin mhrv-rs-ui
69107

70108
- name: Package (unix)
71109
if: runner.os != 'Windows'
72110
run: |
73111
mkdir -p dist
74-
cp target/${{ matrix.target }}/release/mhrv-rs dist/${{ matrix.name }}
75-
chmod +x dist/${{ matrix.name }}
112+
cp target/${{ matrix.target }}/release/mhrv-rs dist/mhrv-rs
113+
chmod +x dist/mhrv-rs
114+
if [ -f target/${{ matrix.target }}/release/mhrv-rs-ui ]; then
115+
cp target/${{ matrix.target }}/release/mhrv-rs-ui dist/mhrv-rs-ui
116+
chmod +x dist/mhrv-rs-ui
117+
fi
118+
119+
- name: Build macOS .app bundle
120+
if: runner.os == 'macOS'
121+
run: |
122+
VER="${GITHUB_REF#refs/tags/v}"
123+
./assets/macos/build-app.sh dist/mhrv-rs-ui "$VER" dist
124+
# Make a clean zip of just the .app for the release
125+
cd dist
126+
zip -qry "${{ matrix.name }}-app.zip" mhrv-rs.app
76127
77128
- name: Package (windows)
78129
if: runner.os == 'Windows'
79130
shell: pwsh
80131
run: |
81-
New-Item -ItemType Directory -Force -Path dist
82-
Copy-Item target/${{ matrix.target }}/release/mhrv-rs.exe dist/${{ matrix.name }}.exe
132+
New-Item -ItemType Directory -Force -Path dist | Out-Null
133+
Copy-Item target/${{ matrix.target }}/release/mhrv-rs.exe dist/mhrv-rs.exe
134+
if (Test-Path target/${{ matrix.target }}/release/mhrv-rs-ui.exe) {
135+
Copy-Item target/${{ matrix.target }}/release/mhrv-rs-ui.exe dist/mhrv-rs-ui.exe
136+
}
137+
138+
- name: Make archive
139+
shell: bash
140+
run: |
141+
cd dist
142+
if [ "${{ runner.os }}" = "Windows" ]; then
143+
7z a -tzip "${{ matrix.name }}.zip" mhrv-rs.exe mhrv-rs-ui.exe
144+
else
145+
tar czf "${{ matrix.name }}.tar.gz" mhrv-rs mhrv-rs-ui 2>/dev/null || tar czf "${{ matrix.name }}.tar.gz" mhrv-rs
146+
fi
83147
84148
- uses: actions/upload-artifact@v4
85149
with:
86150
name: ${{ matrix.name }}
87-
path: dist/${{ matrix.name }}${{ runner.os == 'Windows' && '.exe' || '' }}
151+
path: |
152+
dist/${{ matrix.name }}.tar.gz
153+
dist/${{ matrix.name }}.zip
154+
dist/${{ matrix.name }}-app.zip
155+
if-no-files-found: ignore
88156

89157
release:
90158
needs: build

0 commit comments

Comments
 (0)