Compare commits

...

8 Commits

Author SHA1 Message Date
6d105a70ad chore: update CHANGELOG.md for v0.2.66 [skip ci] 2026-04-15 02:11:31 +00:00
ca56b583c5 Merge pull request 'feat: implement dynamic versioning from Git tags' (#42) from fix/version-dynamic-build into master
All checks were successful
Auto Tag / autotag (push) Successful in 12s
Auto Tag / wiki-sync (push) Successful in 13s
Auto Tag / changelog (push) Successful in 41s
Auto Tag / build-linux-amd64 (push) Successful in 13m51s
Auto Tag / build-linux-arm64 (push) Successful in 15m41s
Auto Tag / build-windows-amd64 (push) Successful in 16m36s
Auto Tag / build-macos-arm64 (push) Successful in 2m22s
Reviewed-on: #42
2026-04-15 02:10:10 +00:00
Shaun Arman
8c35e91aef Merge branch 'master' into fix/version-dynamic-build
Some checks failed
Test / rust-fmt-check (pull_request) Successful in 1m8s
Test / frontend-typecheck (pull_request) Successful in 1m17s
Test / frontend-tests (pull_request) Successful in 1m23s
PR Review Automation / review (pull_request) Failing after 2m11s
Test / rust-clippy (pull_request) Successful in 6m11s
Test / rust-tests (pull_request) Successful in 9m7s
2026-04-14 21:09:11 -05:00
Shaun Arman
1055841b6f fix: remove invalid --locked flag from cargo commands and fix format string
All checks were successful
Test / rust-fmt-check (pull_request) Successful in 1m3s
PR Review Automation / review (pull_request) Successful in 2m54s
Test / frontend-typecheck (pull_request) Successful in 1m14s
Test / frontend-tests (pull_request) Successful in 1m25s
Test / rust-clippy (pull_request) Successful in 8m1s
Test / rust-tests (pull_request) Successful in 10m11s
- Remove --locked flag from cargo fmt, clippy, and test commands in CI
- Update build.rs to use Rust 2021 direct variable interpolation in format strings
2026-04-14 20:50:47 -05:00
f38ca7e2fc chore: update CHANGELOG.md for v0.2.63 [skip ci] 2026-04-15 01:45:29 +00:00
Shaun Arman
9248811076 fix: add --locked to cargo commands and improve version update script
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 1m11s
Test / frontend-typecheck (pull_request) Successful in 1m18s
Test / frontend-tests (pull_request) Successful in 1m21s
Test / rust-clippy (pull_request) Failing after 3m25s
PR Review Automation / review (pull_request) Successful in 3m37s
Test / rust-tests (pull_request) Successful in 5m9s
- Add --locked to fmt, clippy, and test commands in CI
- Remove updateCargoLock() and rely on cargo generate-lockfile
- Add .git directory existence check in update-version.mjs
- Use package.json as dynamic fallback instead of hardcoded 0.2.50
- Ensure execSync uses shell: false explicitly
2026-04-13 17:54:16 -05:00
Shaun Arman
007d0ee9d5 chore: fix version update implementation
All checks were successful
PR Review Automation / review (pull_request) Successful in 2m18s
- Replace npm ci with npm install in CI
- Remove --locked flag from cargo clippy/test
- Add cargo generate-lockfile after version update
- Update update-version.mjs with semver validation
- Add build.rs for Rust-level version injection
2026-04-13 16:34:48 -05:00
Shaun Arman
9e1a9b1d34 feat: implement dynamic versioning from Git tags
Some checks failed
Test / rust-clippy (pull_request) Failing after 15s
Test / rust-tests (pull_request) Failing after 19s
Test / rust-fmt-check (pull_request) Successful in 55s
Test / frontend-typecheck (pull_request) Successful in 1m22s
Test / frontend-tests (pull_request) Successful in 1m26s
PR Review Automation / review (pull_request) Successful in 2m57s
- Add build.rs to read version from git describe --tags
- Create update-version.mjs script to sync version across files
- Add get_app_version() command to Rust backend
- Update App.tsx to use custom version command
- Run version update in CI before Rust checks
2026-04-13 16:12:03 -05:00
12 changed files with 214 additions and 14 deletions

View File

@ -37,6 +37,11 @@ jobs:
key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-linux-amd64-
- name: Install dependencies
run: npm install --legacy-peer-deps
- name: Update version from Git
run: node scripts/update-version.mjs
- run: cargo generate-lockfile --manifest-path src-tauri/Cargo.toml
- run: cargo fmt --manifest-path src-tauri/Cargo.toml --check
rust-clippy:
@ -72,7 +77,7 @@ jobs:
key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-linux-amd64-
- run: cargo clippy --locked --manifest-path src-tauri/Cargo.toml -- -D warnings
- run: cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
rust-tests:
runs-on: ubuntu-latest
@ -107,7 +112,7 @@ jobs:
key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-linux-amd64-
- run: cargo test --locked --manifest-path src-tauri/Cargo.toml -- --test-threads=1
- run: cargo test --manifest-path src-tauri/Cargo.toml -- --test-threads=1
frontend-typecheck:
runs-on: ubuntu-latest

View File

@ -4,18 +4,53 @@ All notable changes to TFTSR are documented here.
Commit types shown: feat, fix, perf, docs, refactor.
CI, chore, and build changes are excluded.
## [Unreleased]
## [0.2.65] — 2026-04-15
### Bug Fixes
- Add --locked to cargo commands and improve version update script
- Remove invalid --locked flag from cargo commands and fix format string
- **integrations**: Security and correctness improvements
- Correct WIQL syntax and escape_wiql implementation
### Features
- Implement dynamic versioning from Git tags
- **integrations**: Implement query expansion for semantic search
### Security
- Fix query expansion issues from PR review
- Address all issues from automated PR review
## [0.2.63] — 2026-04-13
### Bug Fixes
- Add Windows nsis target and update CHANGELOG to v0.2.61
## [0.2.61] — 2026-04-13
### Bug Fixes
- Remove AppImage from upload artifact patterns
## [0.2.59] — 2026-04-13
### Bug Fixes
- Remove AppImage bundling to fix linux-amd64 build
## [0.2.57] — 2026-04-13
### Bug Fixes
- Add missing ai_providers columns and fix linux-amd64 build
- Address AI review findings
- Address critical AI review issues
- Add fuse dependency for AppImage support
### Refactoring
- Remove custom linuxdeploy install per CI CI uses tauri-downloaded version
- Revert to original Dockerfile without manual linuxdeploy installation
## [0.2.56] — 2026-04-13
### Bug Fixes
- Add missing ai_providers columns and fix linux-amd64 build
- Address AI review findings
- Address critical AI review issues
## [0.2.55] — 2026-04-13
### Bug Fixes

View File

@ -1,11 +1,12 @@
{
"name": "tftsr",
"private": true,
"version": "0.2.50",
"version": "0.2.62",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"version:update": "node scripts/update-version.mjs",
"preview": "vite preview",
"tauri": "tauri",
"test": "vitest",

111
scripts/update-version.mjs Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env node
import { execSync } from 'child_process';
import { readFileSync, writeFileSync, existsSync, mkdirSync } 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, '..');
/**
* Validate version is semver-compliant (X.Y.Z)
*/
function isValidSemver(version) {
return /^[0-9]+\.[0-9]+\.[0-9]+$/.test(version);
}
function validateGitRepo(root) {
if (!existsSync(resolve(root, '.git'))) {
throw new Error(`Not a Git repository: ${root}`);
}
}
function getVersionFromGit() {
validateGitRepo(projectRoot);
try {
const output = execSync('git describe --tags --abbrev=0', {
encoding: 'utf-8',
cwd: projectRoot,
shell: false
});
let version = output.trim();
// Remove v prefix
version = version.replace(/^v/, '');
// Validate it's a valid semver
if (!isValidSemver(version)) {
const pkgJsonVersion = getFallbackVersion();
console.warn(`Invalid version format "${version}" from git describe, using package.json fallback: ${pkgJsonVersion}`);
return pkgJsonVersion;
}
return version;
} catch (e) {
const pkgJsonVersion = getFallbackVersion();
console.warn(`Failed to get version from Git tags, using package.json fallback: ${pkgJsonVersion}`);
return pkgJsonVersion;
}
}
function getFallbackVersion() {
const pkgPath = resolve(projectRoot, 'package.json');
if (!existsSync(pkgPath)) {
return '0.2.50';
}
try {
const content = readFileSync(pkgPath, 'utf-8');
const json = JSON.parse(content);
return json.version || '0.2.50';
} catch {
return '0.2.50';
}
}
function updatePackageJson(version) {
const fullPath = resolve(projectRoot, 'package.json');
if (!existsSync(fullPath)) {
throw new Error(`File not found: ${fullPath}`);
}
const content = readFileSync(fullPath, 'utf-8');
const json = JSON.parse(content);
json.version = version;
// Write with 2-space indentation
writeFileSync(fullPath, JSON.stringify(json, null, 2) + '\n', 'utf-8');
console.log(`✓ Updated package.json to ${version}`);
}
function updateTOML(path, version) {
const fullPath = resolve(projectRoot, path);
if (!existsSync(fullPath)) {
throw new Error(`File not found: ${fullPath}`);
}
const content = readFileSync(fullPath, 'utf-8');
const lines = content.split('\n');
const output = [];
for (const line of lines) {
if (line.match(/^\s*version\s*=\s*"/)) {
output.push(`version = "${version}"`);
} else {
output.push(line);
}
}
writeFileSync(fullPath, output.join('\n') + '\n', 'utf-8');
console.log(`✓ Updated ${path} to ${version}`);
}
const version = getVersionFromGit();
console.log(`Setting version to: ${version}`);
updatePackageJson(version);
updateTOML('src-tauri/Cargo.toml', version);
updateTOML('src-tauri/tauri.conf.json', version);
console.log(`✓ All version fields updated to ${version}`);

2
src-tauri/Cargo.lock generated
View File

@ -6139,7 +6139,7 @@ dependencies = [
[[package]]
name = "trcaa"
version = "0.2.50"
version = "0.2.62"
dependencies = [
"aes-gcm",
"aho-corasick",

View File

@ -1,6 +1,6 @@
[package]
name = "trcaa"
version = "0.2.50"
version = "0.2.62"
edition = "2021"
[lib]
@ -53,3 +53,7 @@ mockito = "1.2"
[profile.release]
opt-level = "s"
strip = true

View File

@ -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()
}

View File

@ -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<String, String> {
env::var("APP_VERSION")
.or_else(|_| env::var("CARGO_PKG_VERSION"))
.map_err(|e| format!("Failed to get version: {e}"))
}

View File

@ -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");

View File

@ -6,7 +6,7 @@
"frontendDist": "../dist",
"devUrl": "http://localhost:1420",
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build"
"beforeBuildCommand": "npm run version:update && npm run build"
},
"app": {
"security": {
@ -41,4 +41,7 @@
"shortDescription": "Troubleshooting and RCA Assistant",
"longDescription": "Structured AI-backed assistant for IT troubleshooting, 5-whys root cause analysis, and post-mortem documentation with offline Ollama support."
}
}
}

View File

@ -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

View File

@ -486,3 +486,8 @@ export const loadAiProvidersCmd = () =>
export const deleteAiProviderCmd = (name: string) =>
invoke<void>("delete_ai_provider", { name });
// ─── System / Version ─────────────────────────────────────────────────────────
export const getAppVersionCmd = () =>
invoke<string>("get_app_version");