





















@@ -3,11 +3,14 @@ import path from "node:path";
33import { describe, expect, it } from "vitest";
44import {
55canonicalAndroidVersionCode,
6+extractChangelogSection,
67normalizeGatewayVersionToPinnedAndroidVersion,
78normalizePinnedAndroidVersion,
9+renderAndroidReleaseNotes,
810renderAndroidVersionProperties,
911resolveAndroidVersion,
1012resolveGatewayVersionForAndroidRelease,
13+syncAndroidVersioning,
1114} from "../../scripts/lib/android-version.ts";
1215import {
1316installAndroidFixtureCleanup,
@@ -25,6 +28,11 @@ describe("resolveAndroidVersion", () => {
25282629expect(resolveAndroidVersion(rootDir)).toEqual({
2730canonicalVersion: "2026.6.2",
31+changelogPath: path.join(rootDir, "apps/android/CHANGELOG.md"),
32+releaseNotesPath: path.join(
33+rootDir,
34+"apps/android/fastlane/metadata/android/en-US/release_notes.txt",
35+),
2836versionCode: 2026060201,
2937versionFilePath: path.join(rootDir, "apps/android/version.json"),
3038versionPropertiesPath: path.join(rootDir, "apps/android/Config/Version.properties"),
@@ -134,3 +142,84 @@ describe("renderAndroidVersionProperties", () => {
134142);
135143});
136144});
145+146+describe("renderAndroidReleaseNotes", () => {
147+it("extracts exact pinned-version notes before Unreleased notes", () => {
148+const rootDir = writeAndroidFixture({
149+version: "2026.6.2",
150+versionCode: 2026060201,
151+changelog: [
152+"# OpenClaw Android Changelog",
153+"",
154+"## Unreleased",
155+"",
156+"Future Android changes.",
157+"",
158+"## 2026.6.2 - 2026-06-02",
159+"",
160+"Pinned Android release notes.",
161+"",
162+].join("\n"),
163+});
164+const version = resolveAndroidVersion(rootDir);
165+166+expect(
167+renderAndroidReleaseNotes(
168+version,
169+"# OpenClaw Android Changelog\n\n## Unreleased\n\nFuture Android changes.\n\n## 2026.6.2 - 2026-06-02\n\nPinned Android release notes.\n",
170+),
171+).toBe("Pinned Android release notes.\n");
172+});
173+174+it("falls back to Unreleased notes while iterating on a release train", () => {
175+const rootDir = writeAndroidFixture({
176+version: "2026.6.2",
177+versionCode: 2026060201,
178+});
179+const version = resolveAndroidVersion(rootDir);
180+181+expect(
182+renderAndroidReleaseNotes(
183+version,
184+"# OpenClaw Android Changelog\n\n## Unreleased\n\nPending Android notes.\n",
185+),
186+).toBe("Pending Android notes.\n");
187+});
188+189+it("rejects changelogs without exact-version or Unreleased notes", () => {
190+const rootDir = writeAndroidFixture({
191+version: "2026.6.2",
192+versionCode: 2026060201,
193+});
194+const version = resolveAndroidVersion(rootDir);
195+196+expect(() =>
197+renderAndroidReleaseNotes(
198+version,
199+"# OpenClaw Android Changelog\n\n## 2026.6.1\n\nOld notes.\n",
200+),
201+).toThrow("Unable to find Android changelog notes for 2026.6.2");
202+});
203+204+it("treats empty changelog sections as absent", () => {
205+expect(
206+extractChangelogSection("## Unreleased\n\n\n## 2026.6.2\n\nNotes.\n", "Unreleased"),
207+).toBeNull();
208+});
209+});
210+211+describe("syncAndroidVersioning", () => {
212+it("syncs generated Gradle version properties and Fastlane release notes", () => {
213+const rootDir = writeAndroidFixture({
214+version: "2026.6.2",
215+versionCode: 2026060201,
216+releaseNotes: "stale notes\n",
217+versionProperties: "stale version\n",
218+});
219+220+expect(syncAndroidVersioning({ mode: "write", rootDir }).updatedPaths).toEqual([
221+path.join(rootDir, "apps/android/Config/Version.properties"),
222+path.join(rootDir, "apps/android/fastlane/metadata/android/en-US/release_notes.txt"),
223+]);
224+});
225+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。