fix: prefer stable release when beta lags
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
checkUpdateStatus,
|
||||
compareSemverStrings,
|
||||
fetchNpmTagVersion,
|
||||
resolveNpmChannelTag,
|
||||
} from "../infra/update-check.js";
|
||||
import { parseSemver } from "../infra/runtime-guard.js";
|
||||
import {
|
||||
@@ -411,10 +412,16 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
|
||||
const gitCheckout = await isGitCheckout(root);
|
||||
const defaultChannel = gitCheckout ? DEFAULT_GIT_CHANNEL : DEFAULT_PACKAGE_CHANNEL;
|
||||
const channel = requestedChannel ?? storedChannel ?? defaultChannel;
|
||||
const tag = normalizeTag(opts.tag) ?? channelToNpmTag(channel);
|
||||
const explicitTag = normalizeTag(opts.tag);
|
||||
let tag = explicitTag ?? channelToNpmTag(channel);
|
||||
if (!gitCheckout) {
|
||||
const currentVersion = await readPackageVersion(root);
|
||||
const targetVersion = await resolveTargetVersion(tag, timeoutMs);
|
||||
const targetVersion = explicitTag
|
||||
? await resolveTargetVersion(tag, timeoutMs)
|
||||
: await resolveNpmChannelTag({ channel, timeoutMs }).then((resolved) => {
|
||||
tag = resolved.tag;
|
||||
return resolved.version;
|
||||
});
|
||||
const cmp =
|
||||
currentVersion && targetVersion ? compareSemverStrings(currentVersion, targetVersion) : null;
|
||||
const needsConfirm =
|
||||
|
||||
@@ -3,6 +3,7 @@ import path from "node:path";
|
||||
|
||||
import { runCommandWithTimeout } from "../process/exec.js";
|
||||
import { parseSemver } from "./runtime-guard.js";
|
||||
import { channelToNpmTag, type UpdateChannel } from "./update-channels.js";
|
||||
|
||||
export type PackageManager = "pnpm" | "bun" | "npm" | "unknown";
|
||||
|
||||
@@ -315,6 +316,30 @@ export async function fetchNpmTagVersion(params: {
|
||||
}
|
||||
}
|
||||
|
||||
export async function resolveNpmChannelTag(params: {
|
||||
channel: UpdateChannel;
|
||||
timeoutMs?: number;
|
||||
}): Promise<{ tag: string; version: string | null }> {
|
||||
const channelTag = channelToNpmTag(params.channel);
|
||||
const channelStatus = await fetchNpmTagVersion({ tag: channelTag, timeoutMs: params.timeoutMs });
|
||||
if (params.channel !== "beta") {
|
||||
return { tag: channelTag, version: channelStatus.version };
|
||||
}
|
||||
|
||||
const latestStatus = await fetchNpmTagVersion({ tag: "latest", timeoutMs: params.timeoutMs });
|
||||
if (!latestStatus.version) {
|
||||
return { tag: channelTag, version: channelStatus.version };
|
||||
}
|
||||
if (!channelStatus.version) {
|
||||
return { tag: "latest", version: latestStatus.version };
|
||||
}
|
||||
const cmp = compareSemverStrings(channelStatus.version, latestStatus.version);
|
||||
if (cmp != null && cmp < 0) {
|
||||
return { tag: "latest", version: latestStatus.version };
|
||||
}
|
||||
return { tag: channelTag, version: channelStatus.version };
|
||||
}
|
||||
|
||||
export function compareSemverStrings(a: string | null, b: string | null): number | null {
|
||||
const pa = parseSemver(a);
|
||||
const pb = parseSemver(b);
|
||||
|
||||
@@ -3,6 +3,7 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
import { type CommandOptions, runCommandWithTimeout } from "../process/exec.js";
|
||||
import { compareSemverStrings } from "./update-check.js";
|
||||
import { DEV_BRANCH, isBetaTag, isStableTag, type UpdateChannel } from "./update-channels.js";
|
||||
import { trimLogTail } from "./restart-sentinel.js";
|
||||
|
||||
@@ -143,8 +144,16 @@ async function resolveChannelTag(
|
||||
channel: Exclude<UpdateChannel, "dev">,
|
||||
): Promise<string | null> {
|
||||
const tags = await listGitTags(runCommand, root, timeoutMs);
|
||||
const predicate = channel === "beta" ? isBetaTag : isStableTag;
|
||||
return tags.find((tag) => predicate(tag)) ?? null;
|
||||
if (channel === "beta") {
|
||||
const betaTag = tags.find((tag) => isBetaTag(tag)) ?? null;
|
||||
const stableTag = tags.find((tag) => isStableTag(tag)) ?? null;
|
||||
if (!betaTag) return stableTag;
|
||||
if (!stableTag) return betaTag;
|
||||
const cmp = compareSemverStrings(betaTag, stableTag);
|
||||
if (cmp != null && cmp < 0) return stableTag;
|
||||
return betaTag;
|
||||
}
|
||||
return tags.find((tag) => isStableTag(tag)) ?? null;
|
||||
}
|
||||
|
||||
async function resolveGitRoot(
|
||||
|
||||
@@ -4,12 +4,8 @@ import path from "node:path";
|
||||
import type { loadConfig } from "../config/config.js";
|
||||
import { resolveStateDir } from "../config/paths.js";
|
||||
import { resolveClawdbotPackageRoot } from "./clawdbot-root.js";
|
||||
import { compareSemverStrings, fetchNpmTagVersion, checkUpdateStatus } from "./update-check.js";
|
||||
import {
|
||||
channelToNpmTag,
|
||||
normalizeUpdateChannel,
|
||||
DEFAULT_PACKAGE_CHANNEL,
|
||||
} from "./update-channels.js";
|
||||
import { compareSemverStrings, resolveNpmChannelTag, checkUpdateStatus } from "./update-check.js";
|
||||
import { normalizeUpdateChannel, DEFAULT_PACKAGE_CHANNEL } from "./update-channels.js";
|
||||
import { VERSION } from "../version.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
|
||||
@@ -84,22 +80,22 @@ export async function runGatewayUpdateCheck(params: {
|
||||
}
|
||||
|
||||
const channel = normalizeUpdateChannel(params.cfg.update?.channel) ?? DEFAULT_PACKAGE_CHANNEL;
|
||||
const tag = channelToNpmTag(channel);
|
||||
const tagStatus = await fetchNpmTagVersion({ tag, timeoutMs: 2500 });
|
||||
if (!tagStatus.version) {
|
||||
const resolved = await resolveNpmChannelTag({ channel, timeoutMs: 2500 });
|
||||
const tag = resolved.tag;
|
||||
if (!resolved.version) {
|
||||
await writeState(statePath, nextState);
|
||||
return;
|
||||
}
|
||||
|
||||
const cmp = compareSemverStrings(VERSION, tagStatus.version);
|
||||
const cmp = compareSemverStrings(VERSION, resolved.version);
|
||||
if (cmp != null && cmp < 0) {
|
||||
const shouldNotify =
|
||||
state.lastNotifiedVersion !== tagStatus.version || state.lastNotifiedTag !== tag;
|
||||
state.lastNotifiedVersion !== resolved.version || state.lastNotifiedTag !== tag;
|
||||
if (shouldNotify) {
|
||||
params.log.info(
|
||||
`update available (${tag}): v${tagStatus.version} (current v${VERSION}). Run: ${formatCliCommand("clawdbot update")}`,
|
||||
`update available (${tag}): v${resolved.version} (current v${VERSION}). Run: ${formatCliCommand("clawdbot update")}`,
|
||||
);
|
||||
nextState.lastNotifiedVersion = tagStatus.version;
|
||||
nextState.lastNotifiedVersion = resolved.version;
|
||||
nextState.lastNotifiedTag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user