test(package): expand upgrade survivor baselines

This commit is contained in:
Vincent Koc
2026-05-01 02:58:26 -07:00
parent 7f58e89731
commit 15adc741ff
7 changed files with 168 additions and 11 deletions

View File

@@ -66,7 +66,11 @@ function acceptsIntent(coverage, id) {
if (!coverage) {
return true;
}
return Array.isArray(coverage.acceptedIntents) && coverage.acceptedIntents.includes(id);
return (
Array.isArray(coverage.acceptedIntents) &&
coverage.acceptedIntents.includes(id) &&
!coverage.skippedIntents?.includes(id)
);
}
function hasCoverage(coverage) {
@@ -189,10 +193,12 @@ function assertConfigSurvived() {
"main agent contextTokens changed",
);
}
assert(
agents.find((agent) => agent?.id === "ops")?.fastModeDefault === true,
"ops fastModeDefault changed",
);
if (!hasCoverage(coverage) || !coverage.skippedIntents?.includes("agent-modern-preferences")) {
assert(
agents.find((agent) => agent?.id === "ops")?.fastModeDefault === true,
"ops fastModeDefault changed",
);
}
}
if (acceptsIntent(coverage, "skills")) {

View File

@@ -35,6 +35,28 @@ function readConfigSection(fileName) {
return JSON.stringify(JSON.parse(fs.readFileSync(fileUrl, "utf8")));
}
function parseReleaseVersion(version) {
const match = /^([0-9]{4})\.([0-9]+)\.([0-9]+)/u.exec(String(version ?? ""));
if (!match) {
return null;
}
return match.slice(1).map((part) => Number.parseInt(part, 10));
}
function isReleaseBefore(version, minimum) {
const parsed = parseReleaseVersion(version);
const minimumParsed = parseReleaseVersion(minimum);
if (!parsed || !minimumParsed) {
return false;
}
for (let index = 0; index < parsed.length; index += 1) {
if (parsed[index] !== minimumParsed[index]) {
return parsed[index] < minimumParsed[index];
}
}
return false;
}
function configSetJsonFile(id, intent, configPath, fileName) {
return {
id,
@@ -112,6 +134,45 @@ function selectedScenario() {
return process.env.OPENCLAW_UPGRADE_SURVIVOR_SCENARIO || "base";
}
function adaptStepForBaseline(step, baselineVersion, summary) {
if (!isReleaseBefore(baselineVersion, "2026.4.0")) {
return step;
}
if (step.id === "plugins-feishu" || step.id === "channels-feishu") {
if (!summary.skippedIntents.includes("feishu-channel")) {
summary.skippedIntents.push("feishu-channel");
}
return null;
}
if (step.id === "agents") {
const agents = JSON.parse(step.argv[3]);
delete agents.defaults?.skills;
for (const agent of agents.list ?? []) {
delete agent.thinkingDefault;
delete agent.fastModeDefault;
delete agent.skills;
}
summary.skippedIntents.push("agent-modern-preferences");
return {
...step,
argv: [...step.argv.slice(0, 3), JSON.stringify(agents), ...step.argv.slice(4)],
};
}
if (step.intent === "plugins") {
const plugins = JSON.parse(step.argv[3]);
plugins.allow = (plugins.allow ?? []).filter((id) => id !== "memory");
delete plugins.entries?.memory;
if (!summary.skippedIntents.includes("memory-plugin-allow")) {
summary.skippedIntents.push("memory-plugin-allow");
}
return {
...step,
argv: [...step.argv.slice(0, 3), JSON.stringify(plugins), ...step.argv.slice(4)],
};
}
return step;
}
function runOpenClaw(step) {
const result = spawnSync("openclaw", step.argv, {
encoding: "utf8",
@@ -156,7 +217,11 @@ function applyRecipe() {
};
for (const step of [...recipe.slice(0, -1), ...scenarioSteps, recipe.at(-1)]) {
const outcome = runOpenClaw(step);
const adaptedStep = adaptStepForBaseline(step, baselineVersion, summary);
if (!adaptedStep) {
continue;
}
const outcome = runOpenClaw(adaptedStep);
summary.steps.push(outcome);
writeJson(summaryPath, summary);
if (!outcome.ok) {

View File

@@ -3,8 +3,7 @@
"model": {
"primary": "openai/gpt-4.1-mini"
},
"contextTokens": 64000,
"skills": ["memory"]
"contextTokens": 64000
},
"list": [
{

View File

@@ -41,6 +41,7 @@ if [ "${OPENCLAW_UPGRADE_SURVIVOR_PUBLISHED_BASELINE:-0}" = "1" ]; then
fi
mkdir -p "$ARTIFACT_DIR"
chmod -R a+rwX "$ARTIFACT_DIR" || true
DOCKER_E2E_PACKAGE_ARGS=()
CANDIDATE_RAW="${OPENCLAW_UPGRADE_SURVIVOR_CANDIDATE:-current}"
@@ -98,6 +99,7 @@ PACKAGE_TGZ="$(docker_e2e_prepare_package_tgz upgrade-survivor "${OPENCLAW_CURRE
docker_e2e_package_mount_args "$PACKAGE_TGZ"
OPENCLAW_TEST_STATE_SCRIPT_B64="$(docker_e2e_test_state_shell_b64 upgrade-survivor upgrade-survivor)"
mkdir -p "$ARTIFACT_DIR"
chmod -R a+rwX "$ARTIFACT_DIR" || true
docker_e2e_build_or_reuse "$IMAGE_NAME" upgrade-survivor "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR" "bare" "$SKIP_BUILD"

View File

@@ -31,6 +31,17 @@ function dedupeSpecs(specs) {
return [...new Set(specs.map(normalizeUpgradeSurvivorBaselineSpec).filter(Boolean))];
}
function readPublishedVersions(file) {
if (!file) {
return undefined;
}
const parsed = JSON.parse(readFileSync(file, "utf8"));
if (!Array.isArray(parsed)) {
throw new Error(`npm versions list must be a JSON array: ${file}`);
}
return new Set(parsed.filter((version) => typeof version === "string"));
}
function stableVersionFromTag(tagName) {
const version = String(tagName ?? "").replace(/^v/u, "");
if (!/^[0-9]{4}\.[0-9]+\.[0-9]+(?:-[0-9]+)?$/u.test(version)) {
@@ -39,7 +50,18 @@ function stableVersionFromTag(tagName) {
return version;
}
function readStableReleases(file) {
function npmPublishedVersion(version, publishedVersions) {
if (!version || !publishedVersions) {
return version;
}
if (publishedVersions.has(version)) {
return version;
}
const baseVersion = version.replace(/-[0-9]+$/u, "");
return publishedVersions.has(baseVersion) ? baseVersion : undefined;
}
function readStableReleases(file, publishedVersions) {
const ansiEscape = new RegExp(`${String.fromCharCode(27)}\\[[0-?]*[ -/]*[@-~]`, "g");
const raw = readFileSync(file, "utf8").replace(ansiEscape, "");
const parsed = JSON.parse(raw);
@@ -50,7 +72,7 @@ function readStableReleases(file) {
.filter((release) => !release.isPrerelease)
.map((release) => ({
publishedAt: release.publishedAt,
version: stableVersionFromTag(release.tagName),
version: npmPublishedVersion(stableVersionFromTag(release.tagName), publishedVersions),
}))
.filter((release) => release.version && release.publishedAt)
.toSorted((a, b) => String(b.publishedAt).localeCompare(String(a.publishedAt)));
@@ -67,7 +89,8 @@ export function resolveReleaseHistory(args) {
}
const includeVersion = args.get("include-version") ?? "2026.4.23";
const preDate = args.get("pre-date") ?? "2026-03-15T00:00:00Z";
const releases = readStableReleases(releasesJson);
const publishedVersions = readPublishedVersions(args.get("npm-versions-json"));
const releases = readStableReleases(releasesJson, publishedVersions);
const versions = releases.slice(0, historyCount).map((release) => release.version);
const exact = releases.find((release) => release.version === includeVersion);
if (exact) {