Skip to content
127 changes: 127 additions & 0 deletions .github/workflows/beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: Beta
run-name: "OpenVCS Beta • Run #${{ github.run_number }} • Beta@${{ github.sha.substring(0, 7) }}"
Comment thread
Jordonbc marked this conversation as resolved.
Outdated

on:
push:
branches: [ Beta ]
workflow_dispatch:

permissions:
contents: write
actions: write

env:
TARGET_REF: Beta
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ vars.SSCCACHE_GHA_ENABLED }}
SCCACHE_CACHE_SIZE: ${{ vars.SSCCACHE_SIZE }}

jobs:
beta:
name: Build & publish Beta
strategy:
fail-fast: false
matrix:
include:
- platform: ubuntu-24.04
args: ''
- platform: windows-latest
args: ''
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout target ref
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TARGET_REF }}
fetch-depth: 0
submodules: recursive
lfs: true

- name: Compute metadata (date, short SHA)
id: meta
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const date = new Date().toISOString().slice(0, 10);
const short = context.sha.substring(0, 7);
core.setOutput('short_sha', short);
core.setOutput('date', date);

- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: Frontend/package-lock.json

- name: Install frontend deps
working-directory: Frontend
run: npm ci

- name: Build frontend
working-directory: Frontend
run: npm run build

- name: Install Rust (stable)
uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 # stable
with:
components: rustfmt, clippy

- name: Setup sccache
uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9

- name: Install Linux deps
if: matrix.platform == 'ubuntu-24.04'
run: |
set -euxo pipefail
sudo apt-get update
sudo apt-get install -y libappindicator3-dev librsvg2-dev patchelf
sudo apt-get install -y libwebkit2gtk-4.1-dev || sudo apt-get install -y libwebkit2gtk-4.0-dev

- name: Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
cache-on-failure: true

- name: Cargo fmt (check)
run: cargo fmt --all -- --check

- name: Cargo clippy
run: cargo clippy --all-targets -- -D warnings

- name: Remove existing 'openvcs-beta' release & tag
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const tag = 'openvcs-beta';
const releases = await github.paginate(github.rest.repos.listReleases, { owner, repo, per_page: 100 });
const rel = releases.find(r => r.tag_name === tag);
if (rel) await github.rest.repos.deleteRelease({ owner, repo, release_id: rel.id });
try {
await github.rest.git.deleteRef({ owner, repo, ref: `tags/${tag}` });
} catch (e) {
if (e.status !== 422) throw e;
}

- name: Build and publish Beta prerelease
uses: tauri-apps/tauri-action@84b9d35b5fc46c1e45415bdb6144030364f7ebc5 # action-v0.6.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FRONTEND_SKIP_BUILD: '1'
OPENVCS_UPDATE_CHANNEL: beta
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_PRIVATE_KEY_PASSWORD }}
with:
projectPath: Backend
tagName: openvcs-beta
releaseName: "OpenVCS Beta ${{ steps.meta.outputs.date }} (${{ env.TARGET_REF }}@${{ steps.meta.outputs.short_sha }})"
releaseBody: |
Beta build from `${{ env.TARGET_REF }}`.
Date (UTC): ${{ steps.meta.outputs.date }}
Commit: ${{ github.sha }} (${{ env.TARGET_REF }}@${{ steps.meta.outputs.short_sha }})
Runner: ${{ runner.os }} • Run #${{ github.run_number }}
releaseDraft: true
Comment thread
Jordonbc marked this conversation as resolved.
prerelease: true
args: ${{ matrix.args }}
9 changes: 6 additions & 3 deletions Backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ fn main() {
let stable = serde_json::Value::String(
"https://github.com/Jordonbc/OpenVCS/releases/latest/download/latest.json".into(),
);
let beta = serde_json::Value::String(
"https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-beta/latest.json".into(),
);
let nightly = serde_json::Value::String(
"https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-nightly/latest.json".into(),
);
Expand All @@ -146,10 +149,10 @@ fn main() {
if let Some(plugins) = json.get_mut("plugins") {
if let Some(updater) = plugins.get_mut("updater") {
let endpoints = match chan.as_str() {
// Beta: check beta first, then stable
"beta" => serde_json::Value::Array(vec![beta.clone(), stable.clone()]),
// Nightly: check nightly first, then stable
"nightly" | "beta" => {
serde_json::Value::Array(vec![nightly.clone(), stable.clone()])
}
"nightly" => serde_json::Value::Array(vec![nightly.clone(), stable.clone()]),
// Stable: stable only
_ => serde_json::Value::Array(vec![stable.clone()]),
};
Expand Down
1 change: 1 addition & 0 deletions Frontend/src/modals/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ <h3 id="settings-title" style="margin:0">Settings</h3>
</label>
<select id="set-update-channel">
<option value="stable">Stable</option>
<option value="beta">Beta</option>
<option value="nightly">Nightly</option>
</select>
</div>
Expand Down
2 changes: 1 addition & 1 deletion Frontend/src/scripts/features/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ function collectSettingsFromForm(root: HTMLElement): GlobalSettings {
theme_pack: themePack || DEFAULT_LIGHT_THEME_ID,
language: get<HTMLSelectElement>('#set-language')?.value,
default_backend: (get<HTMLSelectElement>('#set-default-backend')?.value || 'git') as any,
update_channel: (() => { const v = get<HTMLSelectElement>('#set-update-channel')?.value; return v === 'beta' ? 'nightly' : v; })(),
update_channel: get<HTMLSelectElement>('#set-update-channel')?.value || 'stable',
Comment thread
Jordonbc marked this conversation as resolved.
reopen_last_repos: !!get<HTMLInputElement>('#set-reopen-last')?.checked,
checks_on_launch: !!get<HTMLInputElement>('#set-checks-on-launch')?.checked,
};
Expand Down
9 changes: 9 additions & 0 deletions Frontend/src/scripts/features/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ export async function showUpdateDialog(_data: any) {
};

const stable = await fetchJson('https://api.github.com/repos/Jordonbc/OpenVCS/releases/latest');
const beta = await fetchJson('https://api.github.com/repos/Jordonbc/OpenVCS/releases/tags/openvcs-beta');
const nightly = await fetchJson('https://api.github.com/repos/Jordonbc/OpenVCS/releases/tags/openvcs-nightly');

const norm = (v: string) => String(v || '').replace(/^v/i, '').trim();
const stableTag = norm(stable?.tag_name || stable?.name || '');
const betaTag = norm(beta?.tag_name || beta?.name || '');
Comment thread
github-code-quality[bot] marked this conversation as resolved.
Fixed
const nightlyTag = norm(nightly?.tag_name || nightly?.name || '');

const base = (v: string) => norm(v).split('+', 1)[0];
Expand All @@ -51,6 +53,13 @@ export async function showUpdateDialog(_data: any) {

if (channel === 'stable') {
if (newerThanCurrent(stableTag)) { show = true; pick = stable; }
} else if (channel === 'beta') {
// Beta: pick the most recent by published_at timestamp between beta and stable
const sDate = Date.parse(String(stable?.published_at || stable?.created_at || '')) || 0;
const bDate = Date.parse(String(beta?.published_at || beta?.created_at || '')) || 0;
pick = (bDate > sDate ? beta : stable) || beta || stable;
const pickTag = norm(pick?.tag_name || pick?.name || '');
show = newerThanCurrent(pickTag);
} else {
// Nightly: pick the most recent by published_at timestamp and ensure it's newer than current
const sDate = Date.parse(String(stable?.published_at || stable?.created_at || '')) || 0;
Expand Down
Loading