Display repository commit count as the Synapsis version

Hop-State: A_06FP98T1AFPC938R80XJ3J0
Hop-Proposal: R_06FP98S721MFZV1BVBVDTK8
Hop-Task: T_06FP98D0VF530A9XJ2HHHWR
Hop-Attempt: AT_06FP98D0VFKNWCN4EJD46YR
This commit is contained in:
2026-07-15 00:17:28 -07:00
committed by Hop
parent 67bd0d0bbb
commit c17b27b240
6 changed files with 48 additions and 5 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ The installer creates:
- Service: `synapsis.service` - Service: `synapsis.service`
- Mandatory update timer: `synapsis-update.timer` - Mandatory update timer: `synapsis-update.timer`
Every node checks `origin/main` about once per minute. When a new commit is available, Synapsis fast-forwards the checkout, replaces the single `backups/latest` database snapshot, installs dependencies, runs migrations, builds, and restarts automatically. The currently deployed commit is shown in the Network Info card and exposed by `/api/version`. Every node checks `origin/main` about once per minute. When a new commit is available, Synapsis fast-forwards the checkout, replaces the single `backups/latest` database snapshot, installs dependencies, runs migrations, builds, and restarts automatically. The repository commit count is shown in the Network Info card; `/api/version` exposes both that number and the full deployed commit hash.
For a node installed before automatic updates existed, bootstrap the timer once with: For a node installed before automatic updates existed, bootstrap the timer once with:
+14
View File
@@ -14,9 +14,23 @@ function getBuildCommit(): string {
} }
} }
function getBuildCommitCount(): string {
if (process.env.APP_COMMIT_COUNT) return process.env.APP_COMMIT_COUNT;
try {
return execFileSync('git', ['rev-list', '--count', 'HEAD'], {
cwd: process.cwd(),
encoding: 'utf8',
}).trim();
} catch {
return 'unknown';
}
}
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
env: { env: {
APP_COMMIT: getBuildCommit(), APP_COMMIT: getBuildCommit(),
APP_COMMIT_COUNT: getBuildCommitCount(),
APP_BUILD_DATE: process.env.APP_BUILD_DATE || new Date().toISOString(), APP_BUILD_DATE: process.env.APP_BUILD_DATE || new Date().toISOString(),
}, },
+4 -3
View File
@@ -32,6 +32,7 @@ export function RightSidebar() {
const [version, setVersion] = useState<{ const [version, setVersion] = useState<{
version: string; version: string;
commit: string | null; commit: string | null;
commitCount: number | null;
buildDate: string | null; buildDate: string | null;
} | null>(null); } | null>(null);
@@ -80,7 +81,7 @@ export function RightSidebar() {
fetch('/api/version') fetch('/api/version')
.then(res => res.json()) .then(res => res.json())
.then(data => setVersion(data)) .then(data => setVersion(data))
.catch(() => setVersion({ version: 'unknown', commit: null, buildDate: null })); .catch(() => setVersion({ version: 'unknown', commit: null, commitCount: null, buildDate: null }));
return () => window.removeEventListener('synapsis:node-updated', handleNodeUpdated); return () => window.removeEventListener('synapsis:node-updated', handleNodeUpdated);
}, []); }, []);
@@ -154,8 +155,8 @@ export function RightSidebar() {
<p style={{ color: 'var(--foreground-secondary)', fontSize: '13px' }}> <p style={{ color: 'var(--foreground-secondary)', fontSize: '13px' }}>
Running{' '} Running{' '}
<a href="https://synapsis.gnosyslabs.xyz" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent)' }}>Synapsis</a> <a href="https://synapsis.gnosyslabs.xyz" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent)' }}>Synapsis</a>
{version?.commit {version?.commitCount !== null && version?.commitCount !== undefined
? ` ${version.commit.slice(0, 7)}` ? ` ${version.commitCount}`
: version?.version : version?.version
? ` ${version.version}` ? ` ${version.version}`
: ''} : ''}
+3 -1
View File
@@ -63,7 +63,9 @@ export async function buildAnnouncement(): Promise<SwarmAnnouncement> {
description, description,
logoUrl, logoUrl,
publicKey, publicKey,
softwareVersion: buildInfo.commit || buildInfo.version, softwareVersion: buildInfo.commitCount !== null
? String(buildInfo.commitCount)
: buildInfo.version,
userCount, userCount,
postCount, postCount,
capabilities, capabilities,
+20
View File
@@ -0,0 +1,20 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import { getCurrentBuildInfo } from './version';
afterEach(() => {
vi.unstubAllEnvs();
});
describe('build information', () => {
it('exposes the repository commit count as a number', () => {
vi.stubEnv('APP_COMMIT_COUNT', '288');
expect(getCurrentBuildInfo().commitCount).toBe(288);
});
it('ignores an unavailable commit count', () => {
vi.stubEnv('APP_COMMIT_COUNT', 'unknown');
expect(getCurrentBuildInfo().commitCount).toBeNull();
});
});
+6
View File
@@ -3,13 +3,19 @@ import packageJson from '../../package.json';
export interface BuildInfo { export interface BuildInfo {
version: string; version: string;
commit: string | null; commit: string | null;
commitCount: number | null;
buildDate: string | null; buildDate: string | null;
} }
export function getCurrentBuildInfo(): BuildInfo { export function getCurrentBuildInfo(): BuildInfo {
const parsedCommitCount = Number.parseInt(process.env.APP_COMMIT_COUNT || '', 10);
return { return {
version: process.env.APP_VERSION || packageJson.version || 'dev', version: process.env.APP_VERSION || packageJson.version || 'dev',
commit: process.env.APP_COMMIT || null, commit: process.env.APP_COMMIT || null,
commitCount: Number.isSafeInteger(parsedCommitCount) && parsedCommitCount >= 0
? parsedCommitCount
: null,
buildDate: process.env.APP_BUILD_DATE || null, buildDate: process.env.APP_BUILD_DATE || null,
}; };
} }