diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-21 11:22:38 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-21 11:22:38 +0000 |
| commit | fcb9e2ef516cff0b6d5168bc6465e4615d2aa96e (patch) | |
| tree | ea490c33061dc0bdc56488f99a355c7626aca348 /bundle/src-tauri/src | |
| parent | 7b94b9003daa1126ce78df37481fc52774c2f0b4 (diff) | |
ci(bundle): publish portable Windows and macOS desktop packages
Build and check Bundle alongside each native compiler. Publish a single
Windows exe with an embedded compiler extracted into the startup directory,
and a macOS tar.xz containing the app and compiler. Check Linux without
publishing a desktop package and require all six nightly attachments.
Include licenses in embedded assets and app resources. Verify local builds,
package smoke checks and release replacement with a simulated GitHub API.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bundle/src-tauri/src')
| -rw-r--r-- | bundle/src-tauri/src/compiler.rs | 41 | ||||
| -rw-r--r-- | bundle/src-tauri/src/main.rs | 9 |
2 files changed, 47 insertions, 3 deletions
diff --git a/bundle/src-tauri/src/compiler.rs b/bundle/src-tauri/src/compiler.rs new file mode 100644 index 0000000..275a707 --- /dev/null +++ b/bundle/src-tauri/src/compiler.rs @@ -0,0 +1,41 @@ +use std::path::PathBuf; + +// Keep startup failures available to the UI, including an unwritable working directory. +pub struct Compiler(pub Result<PathBuf, String>); + +impl Compiler { + pub fn load() -> Self { + Self(executable().map_err(|error| format!("Cannot load compiler: {error}"))) + } +} + +#[cfg(not(windows))] +fn executable() -> std::io::Result<PathBuf> { + Ok(std::env::current_exe()?.with_file_name("cpsc")) +} + +#[cfg(windows)] +fn executable() -> std::io::Result<PathBuf> { + use std::{ + fs::{self, File}, + io, + }; + + let directory = std::env::current_dir()?; + let destination = directory.join("cpsc.exe"); + let staged = directory.join(format!(".cpsc-{}.tmp", std::process::id())); + let result = (|| { + let mut compressed = flate2::read::GzDecoder::new( + &include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/binaries/cpsc.exe.gz"))[..], + ); + let mut file = File::create(&staged)?; + io::copy(&mut compressed, &mut file)?; + drop(file); + fs::rename(&staged, &destination)?; + Ok(destination) + })(); + if result.is_err() { + let _ = fs::remove_file(staged); + } + result +} diff --git a/bundle/src-tauri/src/main.rs b/bundle/src-tauri/src/main.rs index 96f040c..07f25b3 100644 --- a/bundle/src-tauri/src/main.rs +++ b/bundle/src-tauri/src/main.rs @@ -1,6 +1,8 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +mod compiler; mod runner; +use compiler::Compiler; use runner::{OutputEvent, Runner}; use tauri::{ipc::Channel, Manager, State}; @@ -20,10 +22,9 @@ async fn run_file( input: String, output: Channel<OutputEvent>, runner: State<'_, Runner>, + compiler: State<'_, Compiler>, ) -> Result<(), String> { - let executable = std::env::current_exe() - .map_err(|error| error.to_string())? - .with_file_name(if cfg!(windows) { "cpsc.exe" } else { "cpsc" }); + let executable = compiler.inner().0.clone()?; let result = runner .run(executable, path.into(), input, |stream, bytes| { let _ = output.send(OutputEvent::Data { @@ -47,9 +48,11 @@ async fn stop_run(runner: State<'_, Runner>) -> Result<(), String> { } fn main() { + let compiler = Compiler::load(); tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) .manage(Runner::default()) + .manage(compiler) .invoke_handler(tauri::generate_handler![ read_file, write_file, run_file, stop_run ]) |
