Skip to content
Open
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
18 changes: 4 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,9 @@ jobs:
# fmt --all runs on all workspace packages so this is handled by
# check_and_test above
- name: Check
run: |
SKIP_INSTALLER_COPY=true cargo check --package installer-gui --verbose
run: NO_FIRMWARE_BIN=true cargo check --package installer-gui --verbose
- name: Run clippy
run: |
SKIP_INSTALLER_COPY=true cargo clippy --package installer-gui --verbose
run: NO_FIRMWARE_BIN=true cargo clippy --package installer-gui --verbose

test_daemon_frontend:
needs: files_changed
Expand Down Expand Up @@ -391,13 +389,10 @@ jobs:
- name: Install tauri dependencies
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev xdg-utils
- name: Build GUI installer
env:
INSTALLER_PATH: "${{ github.workspace }}/installer-${{ matrix.platform.name }}/installer"
shell: bash
run: |
cd installer-gui
npm install
chmod +x "$INSTALLER_PATH"
npm run tauri build -- --target ${{ matrix.platform.target }}
- uses: actions/upload-artifact@v4
with:
Expand All @@ -421,7 +416,8 @@ jobs:
contents: read
packages: write
needs:
- build_rust_installer
- build_rayhunter
- build_rootshell
- files_changed
- installer_gui_check
- test_installer_frontend
Expand All @@ -441,13 +437,10 @@ jobs:
targets: ${{ matrix.platform.target }}
- uses: Swatinem/rust-cache@v2
- name: Build GUI installer
env:
INSTALLER_PATH: "${{ github.workspace }}/installer-${{ matrix.platform.name }}/installer"
shell: bash
run: |
cd installer-gui
npm install
chmod +x "$INSTALLER_PATH"
npm run tauri build -- --target ${{ matrix.platform.target }}
cd ..
mv "target/${{ matrix.platform.target }}/release/bundle/macos/"*.app .
Expand Down Expand Up @@ -480,12 +473,9 @@ jobs:
- uses: Swatinem/rust-cache@v2
- name: Build GUI installer
shell: bash
env:
INSTALLER_PATH: "${{ github.workspace }}/installer-windows-x86_64/installer.exe"
run: |
cd installer-gui
npm install
chmod +x "$INSTALLER_PATH"
npm run tauri build -- --target ${{ env.TARGET }}
- uses: actions/upload-artifact@v4
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
/book
.DS_Store
installer-gui/src-tauri/gen/
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions installer-gui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,22 @@ You'll need to install [Tauri's dependencies](https://tauri.app/start/prerequisi

### Rayhunter CLI Installer

The Rayhunter GUI installer currently just bundles and wraps the CLI Rayhunter installer. When building the GUI installer, the CLI installer needs to be built and available for bundling. By default it assumed the installer is present in the repo's `target` directory at either `debug/installer` or `release/installer` depending on whether you're doing a debug or release build of the GUI installer.
The GUI installer pulls in the CLI installer as a library. Like with the CLI installer, the firmware binary needs to be present and can be overridden with the same envvars. See `../installer/build.rs` for options.

You can use a different path by setting the environment variable INSTALLER_PATH when the GUI installer being built. You can also use the environment variable SKIP_INSTALLER_COPY which leaves any previously bundled CLI installer unmodified or if one does not exist bundles a dummy installer file allowing the GUI installer to be successfully built.
For example, to build the firmware in development mode and then provide the path explicitly:

```bash
cargo build-daemon-firmware-devel

(cd installer-gui && FILE_RAYHUNTER_DAEMON=$PWD/../target/armv7-unknown-linux-musleabihf/firmware-devel/rayhunter-daemon npm run tauri android build)
```

## Building

After preparing dependencies, the GUI installer can be built by:

1. Running `npm install` in this directory.
2. Setting INSTALLER_PATH or SKIP_INSTALLER_COPY if desired and running `npm run tauri dev`.
2. Running `npm run tauri dev`.

This will build the GUI installer in development mode. While this command is running, any changes to either the frontend or backend code will cause the installer to be reloaded or rebuilt.

Expand Down
1 change: 0 additions & 1 deletion installer-gui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion installer-gui/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-plugin-shell = "2"
anyhow = "1.0.100"

installer = { path = "../../installer" }
49 changes: 0 additions & 49 deletions installer-gui/src-tauri/build.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,3 @@
use std::env::consts::EXE_SUFFIX;
use std::path::PathBuf;

fn main() {
println!("cargo::rerun-if-env-changed=INSTALLER_PATH");
println!("cargo::rerun-if-env-changed=SKIP_INSTALLER_COPY");

let destination = get_installer_destination();
if std::env::var_os("SKIP_INSTALLER_COPY").is_none() {
let cli_installer =
std::env::var_os("INSTALLER_PATH").map_or_else(default_installer_path, PathBuf::from);
if !cli_installer.exists() {
println!(
"cargo::error=CLI installer binary not present at {}",
cli_installer.display()
);
std::process::exit(0);
}
std::fs::copy(&cli_installer, &destination).unwrap();
println!("cargo::rerun-if-changed={}", cli_installer.display());
println!("cargo::rerun-if-changed={}", destination.display());
} else if !destination.exists() {
// if SKIP_INSTALLER_COPY is set, make sure something exists at destination so the build succeeds
std::fs::write(&destination, []).unwrap();
}

tauri_build::build()
}

fn default_installer_path() -> PathBuf {
// the approach used here was taken from https://github.com/rust-lang/cargo/issues/9661#issuecomment-1722358176
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let profile = std::env::var("PROFILE").unwrap();
let profile_dir = out_dir
.ancestors()
.find(|&path| path.ends_with(&profile))
.unwrap();

profile_dir.join(format!("installer{EXE_SUFFIX}"))
}

fn get_installer_destination() -> PathBuf {
// tauri expects included binaries to have the target triple appended to the file name like
// this. see https://tauri.app/develop/sidecar/
let target_triple = std::env::var("TARGET").unwrap();
[
"binaries",
&format!("installer-cli-{target_triple}{EXE_SUFFIX}"),
]
.iter()
.collect()
}
33 changes: 11 additions & 22 deletions installer-gui/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
use anyhow::Context;
use tauri::Emitter;
use tauri_plugin_shell::ShellExt;
use tauri_plugin_shell::process::CommandEvent;

async fn run_installer(app_handle: tauri::AppHandle, args: String) -> anyhow::Result<()> {
let (mut rx, _child) = app_handle
.shell()
.sidecar("installer-cli")
.context("Error preparing Rayhunter CLI installer to be run")?
.args(args.split_whitespace())
.spawn()
.context("Error launching Rayhunter CLI installer")?;
while let Some(event) = rx.recv().await {
match event {
CommandEvent::Stdout(line_bytes) | CommandEvent::Stderr(line_bytes) => {
let line = String::from_utf8(line_bytes)
.context("Error parsing Rayhunter CLI installer output")?;
tauri::async_runtime::spawn_blocking(move || {
installer::run_with_callback(
// TODO: we should split using something similar to shlex in python
args.split_whitespace().map(String::from).collect(),
Some(Box::new(move |output| {
app_handle
.emit("installer-output", &line)
.context("Error sending Rayhunter CLI installer output to GUI frontend")?;
}
_ => (),
};
}
Ok(())
.emit("installer-output", output)
.expect("Error sending Rayhunter CLI installer output to GUI frontend");
})),
)
})
.await?
}

#[tauri::command]
Expand Down
1 change: 0 additions & 1 deletion installer-gui/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"bundle": {
"active": true,
"targets": ["app", "appimage", "deb", "msi", "nsis", "rpm"],
"externalBin": ["binaries/installer-cli"],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
Expand Down
10 changes: 9 additions & 1 deletion installer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ name = "installer"
version = "0.8.0"
edition = "2024"

[lib]
name = "installer"
crate-type = ["rlib"]

[[bin]]
name = "installer"
path = "src/main.rs"

[dependencies]
aes = "0.8.4"
anyhow = "1.0.98"
Expand All @@ -24,7 +32,7 @@ tokio = { version = "1.44.2", features = ["io-util", "macros", "rt"], default-fe
tokio-retry2 = "0.5.7"
tokio-stream = "0.1.17"

[target.'cfg(target_os = "linux")'.dependencies.adb_client]
[target.'cfg(all(target_os = "linux", not(target_os = "android")))'.dependencies.adb_client]
Copy link
Collaborator

@oopsbagel oopsbagel Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were running into problems on Android?

e: We spoke OOB: yes we were.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. fwiw i have not added any CI for android because I am building the installer in another project. trying to keep the changes here relatively light. I've not really dug into the build failures for adb_client but all the USB installers are not really useful on Android anyway.

git = "https://github.com/EFForg/adb_client.git"
rev = "e511662394e4fa32865c154c40f81a3d846f700c"
default-features = false
Expand Down
Loading
Loading