mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-30 17:50:07 +08:00
e700fd4977
Maintain a CHANGELOG.md (Keep a Changelog format) at the repo root and surface it on the admin About page: - The page now shows the running build's short commit hash next to the version, linked to the GitHub commit. Commit is injected at build time via a new resolveAppCommit() (ZPAN_APP_COMMIT -> WORKERS_CI_COMMIT_SHA -> git rev-parse), wired through vite/tsup defines, the node entry, Docker, and CI. - A new admin-only GET /api/system/changelog endpoint fetches CHANGELOG.md from master on GitHub, caches it, parses the latest released version, and reports whether an update is available (semver compare against the running version). - The About page renders a "latest version" row with an update-available badge and a side drawer that displays the changelog markdown. Tests cover the semver compare, changelog parse/fetch caching, the API wrapper, and the route (admin-gated, parsed payload). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
19 lines
689 B
TypeScript
19 lines
689 B
TypeScript
// Minimal semver comparison for the version freshness check on the About page.
|
|
// Compares the major.minor.patch core only; any pre-release/build suffix is
|
|
// ignored. Returns 1 if a > b, -1 if a < b, 0 if equal or either is unparseable.
|
|
export function compareSemver(a: string, b: string): number {
|
|
const parse = (v: string): [number, number, number] | null => {
|
|
const m = v.trim().match(/^v?(\d+)\.(\d+)\.(\d+)/)
|
|
if (!m) return null
|
|
return [Number(m[1]), Number(m[2]), Number(m[3])]
|
|
}
|
|
const pa = parse(a)
|
|
const pb = parse(b)
|
|
if (!pa || !pb) return 0
|
|
for (let i = 0; i < 3; i++) {
|
|
if (pa[i] > pb[i]) return 1
|
|
if (pa[i] < pb[i]) return -1
|
|
}
|
|
return 0
|
|
}
|