diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index c4347717..fa50091e 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -37,6 +37,10 @@ jobs: key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-linux-amd64- + - name: Update version from Git + run: | + npm ci --legacy-peer-deps + node scripts/update-version.mjs - run: cargo fmt --manifest-path src-tauri/Cargo.toml --check rust-clippy: diff --git a/scripts/update-version.mjs b/scripts/update-version.mjs new file mode 100644 index 00000000..de91f1ed --- /dev/null +++ b/scripts/update-version.mjs @@ -0,0 +1,57 @@ +#!/usr/bin/env node + +import { execSync } from 'child_process'; +import { readFileSync, writeFileSync, existsSync } from 'fs'; +import { resolve, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const projectRoot = resolve(__dirname, '..'); + +function getVersionFromGit() { + try { + const output = execSync('git describe --tags --abbrev=0', { + encoding: 'utf-8', + cwd: projectRoot + }); + const version = output.trim().replace(/^v/, ''); + if (version) { + return version; + } + } catch (e) { + console.warn('Failed to get version from Git tags, using fallback'); + } + return '0.2.50'; +} + +function updateFile(filePath, updater) { + const fullPath = resolve(projectRoot, filePath); + if (!existsSync(fullPath)) { + throw new Error(`File not found: ${fullPath}`); + } + const content = readFileSync(fullPath, 'utf-8'); + const updated = updater(content); + writeFileSync(fullPath, updated, 'utf-8'); + console.log(`✓ Updated ${filePath}`); +} + +const version = getVersionFromGit(); +console.log(`Setting version to: ${version}`); + +// Update Cargo.toml (Rust) +updateFile('src-tauri/Cargo.toml', (content) => { + return content.replace(/version = "([^"]+)"/, `version = "${version}"`); +}); + +// Update package.json (Frontend) +updateFile('package.json', (content) => { + return content.replace(/"version": "([^"]+)"/, `"version": "${version}"`); +}); + +// Update tauri.conf.json +updateFile('src-tauri/tauri.conf.json', (content) => { + return content.replace(/"version": "([^"]+)"/, `"version": "${version}"`); +}); + +console.log(`✓ All version fields updated to ${version}`); diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index a201eec9..f8de467c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -6139,7 +6139,7 @@ dependencies = [ [[package]] name = "trcaa" -version = "0.2.50" +version = "0.2.62" dependencies = [ "aes-gcm", "aho-corasick", diff --git a/src-tauri/build.rs b/src-tauri/build.rs index d860e1e6..03a1b039 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,30 @@ fn main() { + let version = get_version_from_git(); + + println!("cargo:rustc-env=APP_VERSION={}", version); + println!("cargo:rerun-if-changed=.git/refs/heads/master"); + println!("cargo:rerun-if-changed=.git/refs/tags"); + tauri_build::build() } + +fn get_version_from_git() -> String { + if let Ok(output) = std::process::Command::new("git") + .arg("describe") + .arg("--tags") + .arg("--abbrev=0") + .output() + { + if output.status.success() { + let version = String::from_utf8_lossy(&output.stdout) + .trim() + .trim_start_matches('v') + .to_string(); + if !version.is_empty() { + return version; + } + } + } + + "0.2.50".to_string() +} diff --git a/src-tauri/src/commands/system.rs b/src-tauri/src/commands/system.rs index 1263a8d8..7ab59e73 100644 --- a/src-tauri/src/commands/system.rs +++ b/src-tauri/src/commands/system.rs @@ -4,6 +4,7 @@ use crate::ollama::{ OllamaStatus, }; use crate::state::{AppSettings, AppState, ProviderConfig}; +use std::env; // --- Ollama commands --- @@ -275,3 +276,11 @@ pub async fn delete_ai_provider( Ok(()) } + +/// Get the application version from build-time environment +#[tauri::command] +pub async fn get_app_version() -> Result { + env::var("APP_VERSION") + .or_else(|_| env::var("CARGO_PKG_VERSION")) + .map_err(|e| format!("Failed to get version: {e}")) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a4780614..cdf319ba 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -120,6 +120,7 @@ pub fn run() { commands::system::get_settings, commands::system::update_settings, commands::system::get_audit_log, + commands::system::get_app_version, ]) .run(tauri::generate_context!()) .expect("Error running Troubleshooting and RCA Assistant application"); diff --git a/src/App.tsx b/src/App.tsx index 076a53fe..ab38ef17 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect } from "react"; -import { getVersion } from "@tauri-apps/api/app"; import { Routes, Route, NavLink, useLocation } from "react-router-dom"; import { Home, @@ -15,7 +14,7 @@ import { Moon, } from "lucide-react"; import { useSettingsStore } from "@/stores/settingsStore"; -import { loadAiProvidersCmd, testProviderConnectionCmd } from "@/lib/tauriCommands"; +import { getAppVersionCmd, loadAiProvidersCmd, testProviderConnectionCmd } from "@/lib/tauriCommands"; import Dashboard from "@/pages/Dashboard"; import NewIssue from "@/pages/NewIssue"; @@ -50,7 +49,7 @@ export default function App() { void useLocation(); useEffect(() => { - getVersion().then(setAppVersion).catch(() => {}); + getAppVersionCmd().then(setAppVersion).catch(() => {}); }, []); // Load providers and auto-test active provider on startup diff --git a/src/lib/tauriCommands.ts b/src/lib/tauriCommands.ts index ef46f452..78ae9962 100644 --- a/src/lib/tauriCommands.ts +++ b/src/lib/tauriCommands.ts @@ -486,3 +486,8 @@ export const loadAiProvidersCmd = () => export const deleteAiProviderCmd = (name: string) => invoke("delete_ai_provider", { name }); + +// ─── System / Version ───────────────────────────────────────────────────────── + +export const getAppVersionCmd = () => + invoke("get_app_version");