test(release): add appcast regression coverage

This commit is contained in:
Sebastian
2026-02-17 10:42:42 -05:00
parent 19a8f8bbf6
commit e0e2184b90
2 changed files with 29 additions and 0 deletions

View File

@@ -25,6 +25,8 @@ Docs: https://docs.openclaw.ai
- Agents: revert accidental per-model thinkingDefault override merge. (#19195) Thanks @sebslight.
- Sessions: revert accidental session transcript permission hardening from PR #18288. (#19224) Thanks @sebslight.
- macOS/Update: correct the Sparkle appcast version for 2026.2.15 so updates are offered again. (#18201)
- Gateway/Auth: clear stale device-auth tokens after device token mismatch errors so re-paired clients can re-auth. (#18201)
- Voice call/Gateway: prevent overlapping closed-loop turn races with per-call turn locking, route transcript dedupe via source-aware fingerprints with strict cache eviction bounds, and harden `voicecall latency` stats for large logs without spread-operator stack overflow. (#19140) Thanks @mbelinky.
- iOS/Onboarding: stop auth Step 3 retry-loop churn by pausing reconnect attempts on unauthorized/missing-token gateway errors and keeping auth/pairing issue state sticky during manual retry. (#19153) Thanks @mbelinky.
- Fix types in all tests. Typecheck the whole repository.

27
test/appcast.test.ts Normal file
View File

@@ -0,0 +1,27 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const APPCAST_URL = new URL("../appcast.xml", import.meta.url);
function expectedSparkleVersion(shortVersion: string): string {
const [year, month, day] = shortVersion.split(".");
if (!year || !month || !day) {
throw new Error(`unexpected short version: ${shortVersion}`);
}
return `${year}${month.padStart(2, "0")}${day.padStart(2, "0")}0`;
}
describe("appcast.xml", () => {
it("uses the expected Sparkle version for 2026.2.15", () => {
const appcast = readFileSync(APPCAST_URL, "utf8");
const shortVersion = "2026.2.15";
const items = Array.from(appcast.matchAll(/<item>[\s\S]*?<\/item>/g)).map((match) => match[0]);
const matchingItem = items.find((item) =>
item.includes(`<sparkle:shortVersionString>${shortVersion}</sparkle:shortVersionString>`),
);
expect(matchingItem).toBeDefined();
const sparkleMatch = matchingItem?.match(/<sparkle:version>([^<]+)<\/sparkle:version>/);
expect(sparkleMatch?.[1]).toBe(expectedSparkleVersion(shortVersion));
});
});