const assert = require("assert"); const fs = require("fs"); const path = require("path"); const { findSafeTarget } = require("../src/services/versioning"); const root = path.join(__dirname, ".."); const releaseVersion = "0.3.5"; const previousStableVersion = "0.3.4"; const priorStableVersion = "0.3.3"; const earliestCompatibleCoreVersion = "0.1.9"; const introducedPlugins = { lumi_transcription: { version: "0.2.4", knowledge: "lumi-transcription" }, now_playing: { version: "0.1.3", knowledge: "now-playing" } }; function readJson(relativePath) { return JSON.parse(fs.readFileSync(path.join(root, relativePath), "utf8")); } function readText(relativePath) { return fs.readFileSync(path.join(root, relativePath), "utf8"); } function escapeRegex(value) { return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function hasVersionHeading(markdown, version) { return new RegExp(`^#{1,3}\\s+\\[?v?${escapeRegex(version)}\\]?(?:\\s|$)`, "m").test(markdown); } const packageJson = readJson("package.json"); const packageLock = readJson("package-lock.json"); const coreManifest = readJson("update-manifest.json"); const releaseIndex = readJson("release-index.json"); assert.equal(packageJson.version, releaseVersion); assert.equal(packageLock.version, releaseVersion); assert.equal(packageLock.packages?.[""]?.version, releaseVersion); assert.equal(coreManifest.version, releaseVersion); assert.equal(coreManifest.channel, "stable"); assert.equal(coreManifest.compatible_from, earliestCompatibleCoreVersion); assert.equal(coreManifest.rollback_safe, true); assert.deepEqual(coreManifest.replaces_versions, ["1.2.0"]); assert.equal(releaseIndex.releases[0].version, releaseVersion); assert.equal(releaseIndex.releases[0].ref, `refs/tags/v${releaseVersion}`); assert.equal(releaseIndex.releases[1].version, previousStableVersion); assert.equal(releaseIndex.releases[1].ref, `refs/tags/v${previousStableVersion}`); assert.equal(releaseIndex.releases[2].version, priorStableVersion); assert.equal(releaseIndex.releases[2].ref, `refs/tags/v${priorStableVersion}`); assert.equal(releaseIndex.releases.at(-1).version, earliestCompatibleCoreVersion); assert.equal(hasVersionHeading(readText("CHANGELOG.md"), releaseVersion), true); assert.match(readText("knowledge/core/lumi-core.md"), new RegExp(`^Version: ${escapeRegex(releaseVersion)}$`, "m")); const safeCoreTarget = findSafeTarget(previousStableVersion, [ ...(Array.isArray(coreManifest.versions) ? coreManifest.versions : []), coreManifest ]); assert.equal(safeCoreTarget.blocked, false); assert.equal(safeCoreTarget.target?.version, releaseVersion); for (const [pluginId, expected] of Object.entries(introducedPlugins)) { const manifest = readJson(`plugins/${pluginId}/plugin.json`); assert.equal(manifest.version, expected.version, `${pluginId} manifest version`); assert.equal(manifest.compatible_from, "0.1.0", `${pluginId} compatible_from`); assert.equal(manifest.channel, "stable", `${pluginId} release channel`); assert.equal(manifest.rollback_safe, true, `${pluginId} rollback metadata`); assert.equal( hasVersionHeading(readText(`plugins/${pluginId}/CHANGELOG.md`), expected.version), true, `${pluginId} changelog heading` ); assert.match( readText(`knowledge/plugins/${expected.knowledge}.md`), new RegExp(`^Version: ${escapeRegex(expected.version)}$`, "m"), `${pluginId} generated knowledge version` ); } const webSearch = readJson("plugins/lumi_ai_web_search/tool_info.json"); assert.equal(webSearch.version, "0.1.1"); assert.equal(webSearch.minimum_lumi_version, "0.2.0"); assert.equal(webSearch.minimum_lumi_ai_version, "0.8.2"); assert.equal(hasVersionHeading(readText("plugins/lumi_ai_web_search/CHANGELOG.md"), webSearch.version), true); console.log("Release metadata verification passed: stable core 0.3.5 after 0.3.4 with synchronized Companion plugin metadata.");