mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 15:40:44 +00:00
feat: support alpha releases
This commit is contained in:
@@ -91,12 +91,14 @@ export function normalizeUpgradeSurvivorBaselineSpec(raw) {
|
||||
}
|
||||
const spec = value.startsWith("openclaw@") ? value : `openclaw@${value}`;
|
||||
if (
|
||||
!/^openclaw@(?:beta|latest|[0-9]{4}\.[0-9]+\.[0-9]+(?:-(?:[0-9]+|beta\.[0-9]+))?)$/u.test(spec)
|
||||
!/^openclaw@(?:alpha|beta|latest|[0-9]{4}\.[0-9]+\.[0-9]+(?:-(?:[0-9]+|alpha\.[0-9]+|beta\.[0-9]+))?)$/u.test(
|
||||
spec,
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`invalid published upgrade survivor baseline: ${JSON.stringify(
|
||||
value,
|
||||
)}. Expected openclaw@latest, openclaw@beta, or openclaw@YYYY.M.D.`,
|
||||
)}. Expected openclaw@latest, openclaw@beta, openclaw@alpha, or openclaw@YYYY.M.D.`,
|
||||
);
|
||||
}
|
||||
return spec;
|
||||
|
||||
@@ -7,7 +7,7 @@ const IOS_VERSION_XCCONFIG_FILE = "apps/ios/Config/Version.xcconfig";
|
||||
const IOS_RELEASE_NOTES_FILE = "apps/ios/fastlane/metadata/en-US/release_notes.txt";
|
||||
|
||||
const PINNED_IOS_VERSION_PATTERN = /^(\d{4}\.\d{1,2}\.\d{1,2})$/u;
|
||||
const GATEWAY_VERSION_PATTERN = /^(\d{4}\.\d{1,2}\.\d{1,2})(?:-(?:beta\.\d+|\d+))?$/u;
|
||||
const GATEWAY_VERSION_PATTERN = /^(\d{4}\.\d{1,2}\.\d{1,2})(?:-(?:alpha\.\d+|beta\.\d+|\d+))?$/u;
|
||||
|
||||
type IosVersionManifest = {
|
||||
version: string;
|
||||
@@ -52,7 +52,7 @@ export function normalizeGatewayVersionToPinnedIosVersion(rawVersion: string): s
|
||||
const match = GATEWAY_VERSION_PATTERN.exec(trimmed);
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
`Invalid gateway version '${rawVersion}'. Expected YYYY.M.D, YYYY.M.D-beta.N, or YYYY.M.D-N.`,
|
||||
`Invalid gateway version '${rawVersion}'. Expected YYYY.M.D, YYYY.M.D-alpha.N, YYYY.M.D-beta.N, or YYYY.M.D-N.`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const STABLE_VERSION_REGEX = /^(?<year>\d{4})\.(?<month>[1-9]\d?)\.(?<day>[1-9]\d?)$/;
|
||||
const ALPHA_VERSION_REGEX =
|
||||
/^(?<year>\d{4})\.(?<month>[1-9]\d?)\.(?<day>[1-9]\d?)-alpha\.(?<alpha>[1-9]\d*)$/;
|
||||
const BETA_VERSION_REGEX =
|
||||
/^(?<year>\d{4})\.(?<month>[1-9]\d?)\.(?<day>[1-9]\d?)-beta\.(?<beta>[1-9]\d*)$/;
|
||||
const CORRECTION_VERSION_REGEX =
|
||||
@@ -8,10 +10,11 @@ const CORRECTION_VERSION_REGEX =
|
||||
* @typedef {object} ParsedReleaseVersion
|
||||
* @property {string} version
|
||||
* @property {string} baseVersion
|
||||
* @property {"stable" | "beta"} channel
|
||||
* @property {"stable" | "alpha" | "beta"} channel
|
||||
* @property {number} year
|
||||
* @property {number} month
|
||||
* @property {number} day
|
||||
* @property {number | undefined} [alphaNumber]
|
||||
* @property {number | undefined} [betaNumber]
|
||||
* @property {number | undefined} [correctionNumber]
|
||||
* @property {Date} date
|
||||
@@ -19,9 +22,9 @@ const CORRECTION_VERSION_REGEX =
|
||||
|
||||
/**
|
||||
* @typedef {object} NpmPublishPlan
|
||||
* @property {"stable" | "beta"} channel
|
||||
* @property {"latest" | "beta"} publishTag
|
||||
* @property {("latest" | "beta")[]} mirrorDistTags
|
||||
* @property {"stable" | "alpha" | "beta"} channel
|
||||
* @property {"latest" | "alpha" | "beta"} publishTag
|
||||
* @property {("latest" | "alpha" | "beta")[]} mirrorDistTags
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -37,13 +40,14 @@ const CORRECTION_VERSION_REGEX =
|
||||
/**
|
||||
* @param {string} version
|
||||
* @param {Record<string, string | undefined>} groups
|
||||
* @param {"stable" | "beta"} channel
|
||||
* @param {"stable" | "alpha" | "beta"} channel
|
||||
* @returns {ParsedReleaseVersion | null}
|
||||
*/
|
||||
function parseDateParts(version, groups, channel) {
|
||||
const year = Number.parseInt(groups.year ?? "", 10);
|
||||
const month = Number.parseInt(groups.month ?? "", 10);
|
||||
const day = Number.parseInt(groups.day ?? "", 10);
|
||||
const alphaNumber = channel === "alpha" ? Number.parseInt(groups.alpha ?? "", 10) : undefined;
|
||||
const betaNumber = channel === "beta" ? Number.parseInt(groups.beta ?? "", 10) : undefined;
|
||||
|
||||
if (
|
||||
@@ -60,6 +64,9 @@ function parseDateParts(version, groups, channel) {
|
||||
if (channel === "beta" && (!Number.isInteger(betaNumber) || (betaNumber ?? 0) < 1)) {
|
||||
return null;
|
||||
}
|
||||
if (channel === "alpha" && (!Number.isInteger(alphaNumber) || (alphaNumber ?? 0) < 1)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const date = new Date(Date.UTC(year, month - 1, day));
|
||||
if (
|
||||
@@ -77,6 +84,7 @@ function parseDateParts(version, groups, channel) {
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
alphaNumber,
|
||||
betaNumber,
|
||||
date,
|
||||
};
|
||||
@@ -97,6 +105,11 @@ export function parseReleaseVersion(version) {
|
||||
return parseDateParts(trimmed, stableMatch.groups, "stable");
|
||||
}
|
||||
|
||||
const alphaMatch = ALPHA_VERSION_REGEX.exec(trimmed);
|
||||
if (alphaMatch?.groups) {
|
||||
return parseDateParts(trimmed, alphaMatch.groups, "alpha");
|
||||
}
|
||||
|
||||
const betaMatch = BETA_VERSION_REGEX.exec(trimmed);
|
||||
if (betaMatch?.groups) {
|
||||
return parseDateParts(trimmed, betaMatch.groups, "beta");
|
||||
@@ -137,7 +150,12 @@ export function compareReleaseVersions(left, right) {
|
||||
}
|
||||
|
||||
if (parsedLeft.channel !== parsedRight.channel) {
|
||||
return parsedLeft.channel === "stable" ? 1 : -1;
|
||||
const rank = { alpha: 0, beta: 1, stable: 2 };
|
||||
return Math.sign(rank[parsedLeft.channel] - rank[parsedRight.channel]);
|
||||
}
|
||||
|
||||
if (parsedLeft.channel === "alpha" && parsedRight.channel === "alpha") {
|
||||
return Math.sign((parsedLeft.alphaNumber ?? 0) - (parsedRight.alphaNumber ?? 0));
|
||||
}
|
||||
|
||||
if (parsedLeft.channel === "beta" && parsedRight.channel === "beta") {
|
||||
@@ -165,6 +183,13 @@ export function resolveNpmPublishPlan(version, currentBetaVersion) {
|
||||
mirrorDistTags: [],
|
||||
};
|
||||
}
|
||||
if (parsedVersion.channel === "alpha") {
|
||||
return {
|
||||
channel: "alpha",
|
||||
publishTag: "alpha",
|
||||
mirrorDistTags: [],
|
||||
};
|
||||
}
|
||||
|
||||
const normalizedCurrentBeta = currentBetaVersion?.trim();
|
||||
if (normalizedCurrentBeta) {
|
||||
|
||||
@@ -46,8 +46,8 @@ export type PublishablePluginPackage = {
|
||||
packageDir: string;
|
||||
packageName: string;
|
||||
version: string;
|
||||
channel: "stable" | "beta";
|
||||
publishTag: "latest" | "beta";
|
||||
channel: "stable" | "alpha" | "beta";
|
||||
publishTag: "latest" | "alpha" | "beta";
|
||||
};
|
||||
|
||||
type PluginReleasePlanItem = PublishablePluginPackage & {
|
||||
@@ -154,7 +154,12 @@ export function collectClawHubPublishablePluginPackages(
|
||||
packageName,
|
||||
version,
|
||||
channel: parsedVersion.channel,
|
||||
publishTag: parsedVersion.channel === "beta" ? "beta" : "latest",
|
||||
publishTag:
|
||||
parsedVersion.channel === "alpha"
|
||||
? "alpha"
|
||||
: parsedVersion.channel === "beta"
|
||||
? "beta"
|
||||
: "latest",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ export type PublishablePluginPackage = {
|
||||
packageDir: string;
|
||||
packageName: string;
|
||||
version: string;
|
||||
channel: "stable" | "beta";
|
||||
publishTag: "latest" | "beta";
|
||||
channel: "stable" | "alpha" | "beta";
|
||||
publishTag: "latest" | "alpha" | "beta";
|
||||
installNpmSpec?: string;
|
||||
};
|
||||
|
||||
@@ -117,7 +117,7 @@ export function resolvePublishablePluginVersion(params: {
|
||||
const parsedVersion = parseReleaseVersion(version);
|
||||
if (parsedVersion === null) {
|
||||
params.validationErrors.push(
|
||||
`${params.extensionId}: package.json version must match YYYY.M.D, YYYY.M.D-N, or YYYY.M.D-beta.N; found "${version}".`,
|
||||
`${params.extensionId}: package.json version must match YYYY.M.D, YYYY.M.D-N, YYYY.M.D-alpha.N, or YYYY.M.D-beta.N; found "${version}".`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
@@ -244,7 +244,7 @@ export function collectPublishablePluginPackageErrors(
|
||||
errors.push("package.json version must be non-empty.");
|
||||
} else if (parseReleaseVersion(packageVersion) === null) {
|
||||
errors.push(
|
||||
`package.json version must match YYYY.M.D, YYYY.M.D-N, or YYYY.M.D-beta.N; found "${packageVersion}".`,
|
||||
`package.json version must match YYYY.M.D, YYYY.M.D-N, YYYY.M.D-alpha.N, or YYYY.M.D-beta.N; found "${packageVersion}".`,
|
||||
);
|
||||
}
|
||||
if (!Array.isArray(extensions) || extensions.length === 0) {
|
||||
|
||||
@@ -64,7 +64,7 @@ type TelegramQaSummary = {
|
||||
};
|
||||
|
||||
const OPENCLAW_PACKAGE_SPEC_RE =
|
||||
/^openclaw@(main|beta|latest|[0-9]{4}\.[1-9][0-9]*\.[1-9][0-9]*(-[1-9][0-9]*|-beta\.[1-9][0-9]*)?)$/u;
|
||||
/^openclaw@(main|alpha|beta|latest|[0-9]{4}\.[1-9][0-9]*\.[1-9][0-9]*(-[1-9][0-9]*|-(alpha|beta)\.[1-9][0-9]*)?)$/u;
|
||||
|
||||
const REQUIRED_TELEGRAM_ENV = [
|
||||
"OPENCLAW_QA_TELEGRAM_GROUP_ID",
|
||||
@@ -75,7 +75,7 @@ const REQUIRED_TELEGRAM_ENV = [
|
||||
export function validateOpenClawPackageSpec(spec: string) {
|
||||
if (!OPENCLAW_PACKAGE_SPEC_RE.test(spec)) {
|
||||
throw new Error(
|
||||
`Package spec must be openclaw@main, openclaw@beta, openclaw@latest, or an exact OpenClaw release version; got: ${spec}`,
|
||||
`Package spec must be openclaw@main, openclaw@alpha, openclaw@beta, openclaw@latest, or an exact OpenClaw release version; got: ${spec}`,
|
||||
);
|
||||
}
|
||||
return spec;
|
||||
|
||||
Reference in New Issue
Block a user