Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9c9e4e1
chore(deps)(deps-dev): bump vite
dependabot[bot] Sep 8, 2025
3414e82
Fixed nightly workflow
Jordonbc Sep 8, 2025
15b1fc4
Merge pull request #13 from Jordonbc/dependabot/npm_and_yarn/Frontend…
Jordonbc Sep 8, 2025
32c55ac
Added file logging
Jordonbc Sep 9, 2025
3143551
Added tooltips and logging
Jordonbc Sep 9, 2025
cb57684
Added logging file
Jordonbc Sep 9, 2025
7f007da
Fixed new files not showing up
Jordonbc Sep 9, 2025
c6dfac9
Fixed Marking in file panel
Jordonbc Sep 9, 2025
52953cb
Added diff view for history
Jordonbc Sep 9, 2025
e5f94b8
Refined commit history review
Jordonbc Sep 9, 2025
74a6cec
Fixed branch switching
Jordonbc Sep 9, 2025
46cd1e4
Merge pull request #14 from Jordonbc/Fix-Switch-Branch
Jordonbc Sep 9, 2025
4714332
Implemented merge and delete functions for branches.
Jordonbc Sep 9, 2025
9855fc2
Merge branch 'Dev' into Fix-Switch-Branch
Jordonbc Sep 10, 2025
3a0066d
Added Shift key to allow for force deletion
Jordonbc Sep 10, 2025
659bf27
Merge pull request #15 from Jordonbc/Fix-Switch-Branch
Jordonbc Sep 10, 2025
44be55b
Added Edit .gitignore and .gitattributes menu options
Jordonbc Sep 10, 2025
2f9751d
Added exit button in file menu
Jordonbc Sep 10, 2025
d861af8
Added branch renaming
Jordonbc Sep 10, 2025
78cb0a9
Merge pull request #16 from Jordonbc/feature/gitignore
Jordonbc Sep 10, 2025
ff1bb36
Fixed settings issue with backend
Jordonbc Sep 10, 2025
2278dd7
Merge branch 'Dev' into feature/gitignore
Jordonbc Sep 10, 2025
c6833ea
Fixed settings and improved backend selection
Jordonbc Sep 10, 2025
1a6d199
Improved readability of try_reopen_last_repo function
Jordonbc Sep 11, 2025
59850eb
Removed Edit and View menus
Jordonbc Sep 11, 2025
f7ee275
Disabled settings that are currently unimplemented
Jordonbc Sep 11, 2025
bb1dd4e
Improved readability
Jordonbc Sep 11, 2025
e2b29ca
Implemented tab width, UI scaling and monospace settings
Jordonbc Sep 11, 2025
6965e7b
Improved verbosity of logs
Jordonbc Sep 11, 2025
7211964
Removed Auto fetch settings
Jordonbc Sep 11, 2025
296be43
Removed watcher debounce and large threshold
Jordonbc Sep 11, 2025
32aec8e
Added auto updater
Jordonbc Sep 11, 2025
f138e03
Separated updater logic for stable and nightly
Jordonbc Sep 11, 2025
663b204
Merge pull request #17 from Jordonbc/feature/gitignore
Jordonbc Sep 11, 2025
2f4de11
Fixed workflows
Jordonbc Sep 11, 2025
279706b
Update about.ts
Jordonbc Sep 11, 2025
e405935
Fixed update dialog
Jordonbc Sep 11, 2025
61a2b0a
Version Bump to 0.1.0-rc.2
Jordonbc Sep 11, 2025
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
63 changes: 59 additions & 4 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
name: Nightly
run-name: "OpenVCS Nightly • Run #${{ github.run_number }} • Dev @ ${{ github.sha }}"

on:
schedule:
# 01:30 UTC daily (02:30 in London during BST)
- cron: '30 1 * * *'
workflow_dispatch:

# Default to least privilege; override per-job as needed
permissions:
contents: read

jobs:
check-changes:
name: Check if Dev changed since last nightly
Expand Down Expand Up @@ -61,7 +66,8 @@ jobs:
needs: check-changes
if: needs.check-changes.outputs.changed == 'true'
permissions:
contents: write
contents: write # create/delete release + tag
actions: write # use GitHub Actions cache (rust-cache / sccache)
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: 'true'
Expand All @@ -83,6 +89,47 @@ jobs:
fetch-depth: 0
lfs: true

- name: Compute metadata (date, short SHA, compare, changelog)
id: meta
uses: actions/github-script@v8
with:
script: |
const short = context.sha.substring(0, 7);
const date = new Date().toISOString().slice(0, 10); // UTC date
const owner = context.repo.owner;
const repo = context.repo.repo;
const basehead = 'openvcs-nightly...Dev';
let compare_url = `${context.serverUrl}/${owner}/${repo}/compare/${basehead}`;
let commit_url = `${context.serverUrl}/${owner}/${repo}/commit/${context.sha}`;
let changelog = '';

try {
const res = await github.rest.repos.compareCommitsWithBasehead({ owner, repo, basehead });
const commits = res?.data?.commits ?? [];
if (commits.length === 0) {
changelog = `No changes detected.`;
} else {
// Include all commits since last nightly tag -> Dev
const items = commits.map(c => {
const sha = (c.sha || '').substring(0, 7);
const msg = (c.commit?.message || '').split('\n')[0];
const author = c.author?.login || c.commit?.author?.name || 'unknown';
return `- ${sha} ${msg} (@${author})`;
});
changelog = items.join('\n');
}
} catch (e) {
// Likely first nightly (tag missing) or compare failed for another reason
changelog = 'First nightly or previous tag unavailable; showing recent commits at Dev.';
compare_url = `${context.serverUrl}/${owner}/${repo}/tree/Dev`;
}

core.setOutput('short_sha', short);
core.setOutput('date', date);
core.setOutput('compare_url', compare_url);
core.setOutput('commit_url', commit_url);
core.setOutput('changelog', changelog);

# ---------- Frontend ----------
- name: Setup Node
uses: actions/setup-node@v5
Expand Down Expand Up @@ -141,16 +188,24 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FRONTEND_SKIP_BUILD: '1'
OPENVCS_UPDATE_CHANNEL: nightly
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_PRIVATE_KEY_PASSWORD }}
with:
projectPath: Backend
tagName: openvcs-nightly
releaseName: "OpenVCS Nightly #${{ github.run_number }}"
releaseName: "OpenVCS Nightly ${{ steps.meta.outputs.date }} (dev@${{ steps.meta.outputs.short_sha }})"
releaseBody: |
Automated nightly from Dev.
Nightly build from Dev branch.
Date (UTC): ${{ steps.meta.outputs.date }}
Compare: ${{ steps.meta.outputs.compare_url }}
Since: ${{ needs.check-changes.outputs.since_sha }}
Ahead (relevant commits): ${{ needs.check-changes.outputs.ahead_count }}
Commit: ${{ github.sha }}
Commit: ${{ github.sha }} (dev@${{ steps.meta.outputs.short_sha }})
Runner: ${{ runner.os }} • Run #${{ github.run_number }}

Changes since last nightly:
${{ steps.meta.outputs.changelog }}
releaseDraft: false
prerelease: true
args: ${{ matrix.args }}
3 changes: 3 additions & 0 deletions .github/workflows/publish-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# We already built the Frontend; tell Backend/Tauri to skip any beforeBuildCommand
FRONTEND_SKIP_BUILD: '1'
OPENVCS_UPDATE_CHANNEL: stable
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_PRIVATE_KEY_PASSWORD }}
with:
# Point the action at your Tauri project (Backend/)
projectPath: Backend
Expand Down
6 changes: 5 additions & 1 deletion Backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "openvcs"
version = "0.1.0-rc.1"
version = "0.1.0-rc.2"
description = "OpenVCS: a lightweight, highly customizable Git GUI built on Rust & Tauri"
authors = ["Jordon Brooks"]
homepage = "https://bbgames.dev"
Expand All @@ -19,6 +19,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
tauri-build = { version = "2.4", default-features = false, features = [] }
serde_json = "1.0"

[features]
default = ["with-git", "with-git-libgit2"] # enable both by default
Expand All @@ -34,6 +35,7 @@ tauri = { version = "2.8", features = [] }
tauri-plugin-opener = "2.5"
serde = { version = "1", features = ["derive"] }
tauri-plugin-dialog = "2.4"
tauri-plugin-updater = "2.9"
tokio = "1.47"
dirs = "6"
regex = "1.11"
Expand All @@ -43,3 +45,5 @@ parking_lot = "0.12"
toml = "0.9.5"
directories = "6"
serde_json = "1.0"
time = { version = "0.3", features = ["local-offset"] }
zip = "5.0"
95 changes: 54 additions & 41 deletions Backend/build.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,60 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;
use std::{env, fs, path::PathBuf, process::Command};

fn main() {
let git = std::process::Command::new("git")
.args(["describe", "--tags", "--always", "--dirty=-modified"])
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.unwrap_or_else(|| "dev".into());

println!("cargo:rustc-env=GIT_DESCRIBE={}", git);

build_frontend();
tauri_build::build();
}
// Base config path (in the Backend crate)
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
let base = manifest_dir.join("tauri.conf.json");

fn build_frontend() {
if env::var_os("FRONTEND_SKIP_BUILD").is_some() {
return;
}

let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let frontend_dir = manifest_dir.join("..").join("Frontend");

// Run `npm run build` in Frontend/
let status = Command::new("npm")
.args(["run", "build"])
.current_dir(&frontend_dir)
.status()
.expect("failed to spawn npm (is Node installed?)");

if !status.success() {
panic!("frontend build failed in {}", frontend_dir.display());
let data = fs::read_to_string(&base).expect("read tauri.conf.json");
let mut json: serde_json::Value = serde_json::from_str(&data).expect("parse tauri.conf.json");

// Compute channel based on environment; default to stable
let chan = env::var("OPENVCS_UPDATE_CHANNEL").unwrap_or_else(|_| "stable".into());

// Locations
let stable = serde_json::Value::String(
"https://github.com/Jordonbc/OpenVCS/releases/latest/download/latest.json".into(),
);
let nightly = serde_json::Value::String(
"https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-nightly/latest.json".into(),
);

// Navigate: plugins.updater.endpoints
if let Some(plugins) = json.get_mut("plugins") {
if let Some(updater) = plugins.get_mut("updater") {
let endpoints = match chan.as_str() {
// Nightly: check nightly first, then stable
"nightly" | "beta" => serde_json::Value::Array(vec![nightly.clone(), stable.clone()]),
// Stable: stable only
_ => serde_json::Value::Array(vec![stable.clone()]),
};
updater["endpoints"] = endpoints;
}
}

// Optional: tell Cargo to rerun if frontend sources change
println!("cargo:rerun-if-changed={}", frontend_dir.join("index.html").display());
println!("cargo:rerun-if-changed={}", frontend_dir.join("src").display());
let assets = frontend_dir.join("assets");
if assets.exists() {
println!("cargo:rerun-if-changed={}", assets.display());
// Provide the generated config via inline JSON env var (must be single-line)
let inline = serde_json::to_string(&json).unwrap();
println!("cargo:rustc-env=TAURI_CONFIG={}", inline);

// Also persist a copy alongside OUT_DIR for debugging (non-fatal if it fails)
if let Ok(out_dir) = env::var("OUT_DIR") {
let out_path = PathBuf::from(out_dir).join("tauri.generated.conf.json");
let _ = fs::write(&out_path, serde_json::to_string_pretty(&json).unwrap());
}
}

// Re-run if the base config changes
println!("cargo:rerun-if-changed={}", base.display());

// Export a GIT_DESCRIBE string for About dialog and diagnostics
let describe = Command::new("git")
.args(["describe", "--always", "--dirty", "--tags"])
.output()
.ok()
.and_then(|o| if o.status.success() { Some(String::from_utf8_lossy(&o.stdout).trim().to_string()) } else { None })
.filter(|s| !s.is_empty())
.unwrap_or_else(|| "dev".into());
println!("cargo:rustc-env=GIT_DESCRIBE={}", describe);

// Proceed with tauri build steps
tauri_build::build();
}
Loading
Loading