diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..cad88d1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,85 @@ +name: Release + +on: + push: + branches: + - 'feature/**' + tags: + - 'v*' + workflow_dispatch: + +jobs: + build-tauri-macos: + runs-on: macos-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '21' + cache: 'maven' + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: front/package-lock.json + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-darwin,x86_64-apple-darwin + + - name: Build backend + working-directory: back + run: ./mvnw clean package -DskipTests + + - name: Download JRE for macOS + run: | + curl -L -o jre-macos.tar.gz "https://api.adoptium.net/v3/binary/latest/21/ga/mac/aarch64/jre/hotspot/normal/eclipse?project=jdk" + mkdir -p front/src-tauri/resources/jre + tar -xzf jre-macos.tar.gz -C front/src-tauri/resources/jre --strip-components=1 + + - name: Copy backend JAR to Tauri resources + run: | + mkdir -p front/src-tauri/resources + cp back/target/quarkus-app/quarkus-run.jar front/src-tauri/resources/ + cp -r back/target/quarkus-app/lib front/src-tauri/resources/ + cp -r back/target/quarkus-app/app front/src-tauri/resources/ + cp -r back/target/quarkus-app/quarkus front/src-tauri/resources/ + + - name: Install frontend dependencies + working-directory: front + run: npm install + + - name: Build Tauri app (Universal macOS) + working-directory: front + run: npm run tauri:build -- --target universal-apple-darwin + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + + - name: Upload macOS artifacts + uses: actions/upload-artifact@v4 + with: + name: macos-app + path: | + front/src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg + front/src-tauri/target/universal-apple-darwin/release/bundle/macos/*.app + if-no-files-found: error + + - name: Create GitHub Release + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v2 + with: + files: | + front/src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg + draft: true + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index bafcb76..fa7b830 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,21 @@ !front/.env !front/.env.development !front/.prettierrc + +# Exceptions - Tauri +!front/src-tauri/ +!front/src-tauri/src/ +!front/src-tauri/src/** +!front/src-tauri/icons/ +!front/src-tauri/icons/** +!front/src-tauri/capabilities/ +!front/src-tauri/capabilities/** +!front/src-tauri/Cargo.toml +!front/src-tauri/build.rs +!front/src-tauri/tauri.conf.json +!front/src-tauri/.gitignore + +# Exceptions - GitHub workflows +!.github/ +!.github/workflows/ +!.github/workflows/** diff --git a/front/package-lock.json b/front/package-lock.json index 8f64f0f..138d6dc 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -1,12 +1,12 @@ { "name": "front", - "version": "0.0.0", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "front", - "version": "0.0.0", + "version": "0.0.1", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", @@ -25,6 +25,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", + "@tauri-apps/cli": "^2.9.2", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", @@ -1411,6 +1412,223 @@ "win32" ] }, + "node_modules/@tauri-apps/cli": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.9.2.tgz", + "integrity": "sha512-aGzdVgxQW6WQ7e5nydPZ/30u8HvltHjO3Ytzf1wOxX1N5Yj2TsjKWRb/AWJlB95Huml3k3c/b6s0ijAvlSo9xw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.9.2", + "@tauri-apps/cli-darwin-x64": "2.9.2", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.2", + "@tauri-apps/cli-linux-arm64-gnu": "2.9.2", + "@tauri-apps/cli-linux-arm64-musl": "2.9.2", + "@tauri-apps/cli-linux-riscv64-gnu": "2.9.2", + "@tauri-apps/cli-linux-x64-gnu": "2.9.2", + "@tauri-apps/cli-linux-x64-musl": "2.9.2", + "@tauri-apps/cli-win32-arm64-msvc": "2.9.2", + "@tauri-apps/cli-win32-ia32-msvc": "2.9.2", + "@tauri-apps/cli-win32-x64-msvc": "2.9.2" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.9.2.tgz", + "integrity": "sha512-g1OtCXydOZFYRUEAyGYdJ2lLaE3l5jk8o+Bro8y2WOLwBLtbWjBoJIVobOKFanfjG/Xr8H/UA+umEVILPhMc2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.9.2.tgz", + "integrity": "sha512-nHHIY33noUmMOyFwAJz0xQyrYIXU+bae8MNos4TGsTo491YWAF2uzr6iW+Bq0N530xDcbe7EyRvDHgK43RmmVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.9.2.tgz", + "integrity": "sha512-Dq17LBdSuzf+fWOKMIyiSao+Fcq4FiQwYYlx3Nk8oafDINc8sVBjC5gv2xp18KzYhk9teSWfmDpD1sj+D3t7uw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.9.2.tgz", + "integrity": "sha512-Pxj5k29Rxj9xEht4gdE744t5HLXTwBojkjYDXXyJ3mE+BEg9hFX5WkStg7OkyZwH60u8NSkDSMpo7MJTH9srmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.9.2.tgz", + "integrity": "sha512-mx82BuD4q3Yj5Zw+LXveZgPaDCnmH2At2LosX1siK77kaD5Ap5FF+FN0V4y+3cwq+Hcrk9AhEUPbHqoNOx1R2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.9.2.tgz", + "integrity": "sha512-Ypm1nnr7k+ECC1+JfDcnxROHt6BX8t/4GplxBvdY68BDXtIcBbdhPWDos7MK+3bDmoaA0WSJbW+DUjpfSkyKgw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.9.2.tgz", + "integrity": "sha512-tg85cGIM9PWwsbQg8m3uah3SfoNapgUr4vhWtkqgeTDZOjQuQ2duTwCH4UiM7acBpbZHNzvRrxSFpv0U53TqQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.9.2.tgz", + "integrity": "sha512-xW8qaz9bcwR35W2gIg7fKG9e1Z34idOsGpD2zIPgxlJyF314B/1qie50hbOqt5AbbXHR4iRpxKE4kA2grqMmkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.9.2.tgz", + "integrity": "sha512-A1PshB8oHdY7zYOPlLD7Om7/aD9sOUVREd765ElIzYDtptWcALwOP9jb22Wi01vDTqxf98E4ZGIcG2gxr4FhiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.9.2.tgz", + "integrity": "sha512-AuCi0Vnc4qkXRLCC58das0u45SmXAjqcOjqF324CBKa1Z7jjNJESm0Sc2oc2G2q6f2eAbAfi34s2iJNaJU1hlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.9.2.tgz", + "integrity": "sha512-kDoejyfvME/mLkR4VofQnmVPTt/smJvoXuE3xgTbUwcUQKqawM8EyQvxOHQosaJYfQphHi7G0ya8UZo3PlDZig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@tiptap/core": { "version": "3.6.6", "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.6.6.tgz", diff --git a/front/package.json b/front/package.json index b205309..6731875 100644 --- a/front/package.json +++ b/front/package.json @@ -1,13 +1,16 @@ { "name": "front", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "tauri": "tauri", + "tauri:dev": "tauri dev", + "tauri:build": "tauri build" }, "dependencies": { "@dnd-kit/core": "^6.3.1", @@ -27,6 +30,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", + "@tauri-apps/cli": "^2.9.2", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "^5.0.4", diff --git a/front/src-tauri/.gitignore b/front/src-tauri/.gitignore new file mode 100644 index 0000000..b07d16c --- /dev/null +++ b/front/src-tauri/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +/gen/schemas + +# Backend resources (generated during build) +/resources/ diff --git a/front/src-tauri/Cargo.toml b/front/src-tauri/Cargo.toml new file mode 100644 index 0000000..828960a --- /dev/null +++ b/front/src-tauri/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "app" +version = "0.1.0" +description = "A Tauri App" +authors = ["you"] +license = "" +repository = "" +edition = "2021" +rust-version = "1.77.2" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "app_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2.5.1", features = [] } + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +log = "0.4" +tauri = { version = "2.9.2", features = [] } +tauri-plugin-log = "2" diff --git a/front/src-tauri/build.rs b/front/src-tauri/build.rs new file mode 100644 index 0000000..795b9b7 --- /dev/null +++ b/front/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/front/src-tauri/capabilities/default.json b/front/src-tauri/capabilities/default.json new file mode 100644 index 0000000..c135d7f --- /dev/null +++ b/front/src-tauri/capabilities/default.json @@ -0,0 +1,11 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "enables the default permissions", + "windows": [ + "main" + ], + "permissions": [ + "core:default" + ] +} diff --git a/front/src-tauri/icons/128x128.png b/front/src-tauri/icons/128x128.png new file mode 100644 index 0000000..77e7d23 Binary files /dev/null and b/front/src-tauri/icons/128x128.png differ diff --git a/front/src-tauri/icons/128x128@2x.png b/front/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..0f7976f Binary files /dev/null and b/front/src-tauri/icons/128x128@2x.png differ diff --git a/front/src-tauri/icons/32x32.png b/front/src-tauri/icons/32x32.png new file mode 100644 index 0000000..98fda06 Binary files /dev/null and b/front/src-tauri/icons/32x32.png differ diff --git a/front/src-tauri/icons/Square107x107Logo.png b/front/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..f35d84f Binary files /dev/null and b/front/src-tauri/icons/Square107x107Logo.png differ diff --git a/front/src-tauri/icons/Square142x142Logo.png b/front/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..1823bb2 Binary files /dev/null and b/front/src-tauri/icons/Square142x142Logo.png differ diff --git a/front/src-tauri/icons/Square150x150Logo.png b/front/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..dc2b22c Binary files /dev/null and b/front/src-tauri/icons/Square150x150Logo.png differ diff --git a/front/src-tauri/icons/Square284x284Logo.png b/front/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..0ed3984 Binary files /dev/null and b/front/src-tauri/icons/Square284x284Logo.png differ diff --git a/front/src-tauri/icons/Square30x30Logo.png b/front/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..60bf0ea Binary files /dev/null and b/front/src-tauri/icons/Square30x30Logo.png differ diff --git a/front/src-tauri/icons/Square310x310Logo.png b/front/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..c8ca0ad Binary files /dev/null and b/front/src-tauri/icons/Square310x310Logo.png differ diff --git a/front/src-tauri/icons/Square44x44Logo.png b/front/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..8756459 Binary files /dev/null and b/front/src-tauri/icons/Square44x44Logo.png differ diff --git a/front/src-tauri/icons/Square71x71Logo.png b/front/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..2c8023c Binary files /dev/null and b/front/src-tauri/icons/Square71x71Logo.png differ diff --git a/front/src-tauri/icons/Square89x89Logo.png b/front/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..2c5e603 Binary files /dev/null and b/front/src-tauri/icons/Square89x89Logo.png differ diff --git a/front/src-tauri/icons/StoreLogo.png b/front/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..17d142c Binary files /dev/null and b/front/src-tauri/icons/StoreLogo.png differ diff --git a/front/src-tauri/icons/icon.icns b/front/src-tauri/icons/icon.icns new file mode 100644 index 0000000..a2993ad Binary files /dev/null and b/front/src-tauri/icons/icon.icns differ diff --git a/front/src-tauri/icons/icon.ico b/front/src-tauri/icons/icon.ico new file mode 100644 index 0000000..06c23c8 Binary files /dev/null and b/front/src-tauri/icons/icon.ico differ diff --git a/front/src-tauri/icons/icon.png b/front/src-tauri/icons/icon.png new file mode 100644 index 0000000..d1756ce Binary files /dev/null and b/front/src-tauri/icons/icon.png differ diff --git a/front/src-tauri/src/lib.rs b/front/src-tauri/src/lib.rs new file mode 100644 index 0000000..c75fa8d --- /dev/null +++ b/front/src-tauri/src/lib.rs @@ -0,0 +1,108 @@ +use std::process::{Command, Child, Stdio}; +use std::io::{BufRead, BufReader}; +use tauri::Manager; + +static mut BACKEND_PROCESS: Option = None; + +fn start_backend(app_handle: &tauri::AppHandle) -> Result<(), Box> { + let resource_path = app_handle.path().resource_dir()?; + + // Path to the backend + let backend_path = resource_path.clone(); + + // Path to bundled JRE + let jre_path = resource_path.join("jre"); + let java_bin = if cfg!(target_os = "windows") { + jre_path.join("bin/java.exe") + } else if cfg!(target_os = "macos") { + // macOS JRE has a different structure when bundled as .app + let macos_jre = jre_path.join("Contents/Home/bin/java"); + if macos_jre.exists() { + macos_jre + } else { + jre_path.join("bin/java") + } + } else { + jre_path.join("bin/java") + }; + + // Use bundled JRE if available, otherwise system java + let java_cmd = if java_bin.exists() { + java_bin.to_str().unwrap().to_string() + } else { + "java".to_string() + }; + + // Start Quarkus backend with stdout/stderr capture + let mut child = Command::new(java_cmd) + .arg("-jar") + .arg(backend_path.join("quarkus-run.jar")) + .current_dir(&backend_path) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + + // Capture stdout in a separate thread + if let Some(stdout) = child.stdout.take() { + std::thread::spawn(move || { + let reader = BufReader::new(stdout); + for line in reader.lines() { + if let Ok(line) = line { + log::info!("[Backend] {}", line); + } + } + }); + } + + // Capture stderr in a separate thread + if let Some(stderr) = child.stderr.take() { + std::thread::spawn(move || { + let reader = BufReader::new(stderr); + for line in reader.lines() { + if let Ok(line) = line { + log::error!("[Backend] {}", line); + } + } + }); + } + + unsafe { + BACKEND_PROCESS = Some(child); + } + + Ok(()) +} + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .plugin( + tauri_plugin_log::Builder::default() + .level(log::LevelFilter::Info) + .build(), + ) + .setup(|app| { + + // Start backend server + let app_handle = app.handle().clone(); + std::thread::spawn(move || { + if let Err(e) = start_backend(&app_handle) { + eprintln!("Failed to start backend: {}", e); + } + }); + + Ok(()) + }) + .on_window_event(|_window, event| { + if let tauri::WindowEvent::Destroyed = event { + // Kill backend when app closes + unsafe { + if let Some(mut child) = BACKEND_PROCESS.take() { + let _ = child.kill(); + } + } + } + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/front/src-tauri/src/main.rs b/front/src-tauri/src/main.rs new file mode 100644 index 0000000..ad5fe83 --- /dev/null +++ b/front/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + app_lib::run(); +} diff --git a/front/src-tauri/tauri.conf.json b/front/src-tauri/tauri.conf.json new file mode 100644 index 0000000..1e2ddc6 --- /dev/null +++ b/front/src-tauri/tauri.conf.json @@ -0,0 +1,46 @@ +{ + "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", + "productName": "ExploraLire", + "version": "0.0.1", + "identifier": "fr.sydher.edu.exploralire", + "build": { + "frontendDist": "../dist", + "devUrl": "http://localhost:5173", + "beforeDevCommand": "npm run dev", + "beforeBuildCommand": "npm run build" + }, + "app": { + "windows": [ + { + "title": "ExploraLire", + "width": 1280, + "height": 800, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "all", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "resources": [ + "resources/*" + ], + "windows": { + "nsis": null + }, + "macOS": { + "minimumSystemVersion": "10.15" + } + } +}