openclaw/scripts/lib/mobile-store-version.ts
Josh Avant cd2724e432
feat(release): automate iOS and Android store releases (#158807)
Add manually triggered iOS Store Release and Android Store Release workflows with the same local release commands. Derive store versions and OpenAI release notes at build time, retain recovery artifacts, and avoid generated metadata commits.

Pin queued releases to their dispatch commit, qualify native iOS behavior before signing, and improve Android screenshots and interrupted artifact recovery.

Validation includes focused release/planner tests, workflow and type checks, native iOS qualification, Android screenshot capture, and historical release-note exercises. CI failure attribution and remaining hosted release verification are documented in the PR.

Closes #158806
2026-09-26 06:28:29 -05:00

22 lines
1 KiB
TypeScript

import { parseReleaseVersion } from "./release-version.mjs";
export const MAX_MOBILE_STORE_REVISION = 9;
export function encodeMobileStoreVersion(gatewayVersion: string, revision: number): string {
const parsed = parseReleaseVersion(gatewayVersion);
if (!parsed || parsed.version !== gatewayVersion || parsed.baseVersion !== gatewayVersion) {
throw new Error(`Invalid mobile gateway version '${gatewayVersion}'. Expected YYYY.M.PATCH.`);
}
if (!Number.isInteger(revision) || revision < 0 || revision > MAX_MOBILE_STORE_REVISION) {
throw new Error(
`Invalid mobile store revision '${revision}'. Expected an integer from 0 to ${MAX_MOBILE_STORE_REVISION}.`,
);
}
// One unpadded revision digit preserves store ordering when the gateway patch increments.
const encodedPatch = Number(`${parsed.patch}${revision}`);
if (!Number.isSafeInteger(encodedPatch)) {
throw new RangeError(`Encoded mobile store version is too large for '${gatewayVersion}'.`);
}
return `${parsed.year}.${parsed.month}.${encodedPatch}`;
}