diff --git a/scripts/README.md b/scripts/README.md index 5f4cf6f5..d6887faf 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -9,6 +9,7 @@ This directory contains scripts for managing version consistency across the mono Updates the version across all package.json files in the monorepo and updates package-lock.json. **Usage:** + ```bash npm run update-version # Example: @@ -16,6 +17,7 @@ npm run update-version 0.14.3 ``` This script will: + 1. Update the version in all package.json files (root, client, server, cli) 2. Update workspace dependencies in the root package.json 3. Run `npm install` to update package-lock.json @@ -26,11 +28,13 @@ This script will: Checks that all packages have consistent versions and that package-lock.json is up to date. **Usage:** + ```bash npm run check-version ``` This script checks: + 1. All package.json files have the same version 2. Workspace dependencies in root package.json match the current version 3. package-lock.json version matches package.json @@ -41,12 +45,14 @@ This check runs automatically in CI on every PR and push to main. ## CI Integration The version consistency check is integrated into the GitHub Actions workflow (`.github/workflows/main.yml`) and will fail the build if: + - Package versions are inconsistent - package-lock.json is out of sync ## Common Workflows ### Bumping version for a release: + ```bash # Update to new version npm run update-version 0.15.0 @@ -63,4 +69,4 @@ git tag 0.15.0 # Push changes and tag git push && git push --tags -``` \ No newline at end of file +``` diff --git a/scripts/check-version-consistency.js b/scripts/check-version-consistency.js index 72fa15f2..379931de 100755 --- a/scripts/check-version-consistency.js +++ b/scripts/check-version-consistency.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -13,39 +13,39 @@ const __dirname = path.dirname(__filename); * Usage: node scripts/check-version-consistency.js */ -console.log('šŸ” Checking version consistency across packages...\n'); +console.log("šŸ” Checking version consistency across packages...\n"); // List of package.json files to check const packagePaths = [ - 'package.json', - 'client/package.json', - 'server/package.json', - 'cli/package.json' + "package.json", + "client/package.json", + "server/package.json", + "cli/package.json", ]; const versions = new Map(); const errors = []; // Read version from each package.json -packagePaths.forEach(packagePath => { - const fullPath = path.join(__dirname, '..', packagePath); - +packagePaths.forEach((packagePath) => { + const fullPath = path.join(__dirname, "..", packagePath); + if (!fs.existsSync(fullPath)) { console.warn(`āš ļø Skipping ${packagePath} - file not found`); return; } try { - const packageJson = JSON.parse(fs.readFileSync(fullPath, 'utf8')); + const packageJson = JSON.parse(fs.readFileSync(fullPath, "utf8")); const version = packageJson.version; const packageName = packageJson.name || packagePath; - + versions.set(packagePath, { name: packageName, version: version, - dependencies: packageJson.dependencies || {} + dependencies: packageJson.dependencies || {}, }); - + console.log(`šŸ“¦ ${packagePath}:`); console.log(` Name: ${packageName}`); console.log(` Version: ${version}`); @@ -55,24 +55,24 @@ packagePaths.forEach(packagePath => { }); if (errors.length > 0) { - console.error('\nāŒ Errors occurred while reading package files:'); - errors.forEach(error => console.error(` - ${error}`)); + console.error("\nāŒ Errors occurred while reading package files:"); + errors.forEach((error) => console.error(` - ${error}`)); process.exit(1); } // Check if all versions match -const allVersions = Array.from(versions.values()).map(v => v.version); +const allVersions = Array.from(versions.values()).map((v) => v.version); const uniqueVersions = [...new Set(allVersions)]; -console.log('\nšŸ“Š Version Summary:'); +console.log("\nšŸ“Š Version Summary:"); console.log(` Total packages: ${versions.size}`); console.log(` Unique versions: ${uniqueVersions.length}`); if (uniqueVersions.length > 1) { - console.error('\nāŒ Version mismatch detected!'); - console.error(' Found versions: ' + uniqueVersions.join(', ')); - - console.error('\n Package versions:'); + console.error("\nāŒ Version mismatch detected!"); + console.error(" Found versions: " + uniqueVersions.join(", ")); + + console.error("\n Package versions:"); versions.forEach((info, path) => { console.error(` - ${path}: ${info.version}`); }); @@ -81,62 +81,68 @@ if (uniqueVersions.length > 1) { } // Check workspace dependencies in root package.json -const rootPackage = versions.get('package.json'); +const rootPackage = versions.get("package.json"); if (rootPackage) { - console.log('\nšŸ”— Checking workspace dependencies...'); + console.log("\nšŸ”— Checking workspace dependencies..."); const expectedVersion = rootPackage.version; let dependencyErrors = false; - + Object.entries(rootPackage.dependencies).forEach(([dep, version]) => { - if (dep.startsWith('@modelcontextprotocol/inspector-')) { + if (dep.startsWith("@modelcontextprotocol/inspector-")) { const expectedDepVersion = `^${expectedVersion}`; if (version !== expectedDepVersion) { - console.error(` āŒ ${dep}: ${version} (expected ${expectedDepVersion})`); + console.error( + ` āŒ ${dep}: ${version} (expected ${expectedDepVersion})`, + ); dependencyErrors = true; } else { console.log(` āœ… ${dep}: ${version}`); } } }); - + if (dependencyErrors) { - errors.push('Workspace dependency versions do not match package versions'); + errors.push("Workspace dependency versions do not match package versions"); } } // Check if package-lock.json is up to date -console.log('\nšŸ”’ Checking package-lock.json...'); -const lockPath = path.join(__dirname, '..', 'package-lock.json'); +console.log("\nšŸ”’ Checking package-lock.json..."); +const lockPath = path.join(__dirname, "..", "package-lock.json"); let lockFileError = false; if (!fs.existsSync(lockPath)) { - console.error(' āŒ package-lock.json not found'); + console.error(" āŒ package-lock.json not found"); lockFileError = true; } else { try { - const lockFile = JSON.parse(fs.readFileSync(lockPath, 'utf8')); + const lockFile = JSON.parse(fs.readFileSync(lockPath, "utf8")); const lockVersion = lockFile.version; const expectedVersion = rootPackage?.version || uniqueVersions[0]; - + if (lockVersion !== expectedVersion) { - console.error(` āŒ package-lock.json version (${lockVersion}) does not match package.json version (${expectedVersion})`); + console.error( + ` āŒ package-lock.json version (${lockVersion}) does not match package.json version (${expectedVersion})`, + ); lockFileError = true; } else { console.log(` āœ… package-lock.json version matches: ${lockVersion}`); } - + // Check workspace package versions in lock file if (lockFile.packages) { const workspacePackages = [ - { path: 'client', name: '@modelcontextprotocol/inspector-client' }, - { path: 'server', name: '@modelcontextprotocol/inspector-server' }, - { path: 'cli', name: '@modelcontextprotocol/inspector-cli' } + { path: "client", name: "@modelcontextprotocol/inspector-client" }, + { path: "server", name: "@modelcontextprotocol/inspector-server" }, + { path: "cli", name: "@modelcontextprotocol/inspector-cli" }, ]; - + workspacePackages.forEach(({ path, name }) => { const lockPkgPath = lockFile.packages[path]; if (lockPkgPath && lockPkgPath.version !== expectedVersion) { - console.error(` āŒ ${name} in lock file: ${lockPkgPath.version} (expected ${expectedVersion})`); + console.error( + ` āŒ ${name} in lock file: ${lockPkgPath.version} (expected ${expectedVersion})`, + ); lockFileError = true; } }); @@ -148,22 +154,24 @@ if (!fs.existsSync(lockPath)) { } // Final result -console.log('\nšŸŽÆ Result:'); +console.log("\nšŸŽÆ Result:"); if (uniqueVersions.length === 1 && errors.length === 0 && !lockFileError) { - console.log(' āœ… Version consistency check passed!'); + console.log(" āœ… Version consistency check passed!"); process.exit(0); } else { - console.error(' āŒ Version consistency check failed!'); + console.error(" āŒ Version consistency check failed!"); if (uniqueVersions.length > 1) { - console.error(' - Package versions are not consistent'); + console.error(" - Package versions are not consistent"); } if (errors.length > 0) { - console.error(' - ' + errors.join('\n - ')); + console.error(" - " + errors.join("\n - ")); } if (lockFileError) { - console.error(' - package-lock.json is out of sync'); + console.error(" - package-lock.json is out of sync"); } - console.error('\nšŸ’” Run "npm run update-version " to fix version inconsistencies'); + console.error( + '\nšŸ’” Run "npm run update-version " to fix version inconsistencies', + ); console.error(' or run "npm install" to update package-lock.json'); process.exit(1); -} \ No newline at end of file +} diff --git a/scripts/update-version.js b/scripts/update-version.js index 7f82b936..91b69f3b 100755 --- a/scripts/update-version.js +++ b/scripts/update-version.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -import fs from 'fs'; -import path from 'path'; -import { execSync } from 'child_process'; -import { fileURLToPath } from 'url'; +import fs from "fs"; +import path from "path"; +import { execSync } from "child_process"; +import { fileURLToPath } from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -17,16 +17,18 @@ const __dirname = path.dirname(__filename); const newVersion = process.argv[2]; if (!newVersion) { - console.error('āŒ Please provide a version number'); - console.error('Usage: node scripts/update-version.js '); - console.error('Example: node scripts/update-version.js 0.14.2'); + console.error("āŒ Please provide a version number"); + console.error("Usage: node scripts/update-version.js "); + console.error("Example: node scripts/update-version.js 0.14.2"); process.exit(1); } // Validate version format const versionRegex = /^\d+\.\d+\.\d+(-[\w.]+)?$/; if (!versionRegex.test(newVersion)) { - console.error('āŒ Invalid version format. Please use semantic versioning (e.g., 1.2.3 or 1.2.3-beta.1)'); + console.error( + "āŒ Invalid version format. Please use semantic versioning (e.g., 1.2.3 or 1.2.3-beta.1)", + ); process.exit(1); } @@ -34,63 +36,69 @@ console.log(`šŸ”„ Updating all packages to version ${newVersion}...`); // List of package.json files to update const packagePaths = [ - 'package.json', - 'client/package.json', - 'server/package.json', - 'cli/package.json' + "package.json", + "client/package.json", + "server/package.json", + "cli/package.json", ]; const updatedFiles = []; // Update version in each package.json -packagePaths.forEach(packagePath => { - const fullPath = path.join(__dirname, '..', packagePath); - +packagePaths.forEach((packagePath) => { + const fullPath = path.join(__dirname, "..", packagePath); + if (!fs.existsSync(fullPath)) { console.warn(`āš ļø Skipping ${packagePath} - file not found`); return; } try { - const packageJson = JSON.parse(fs.readFileSync(fullPath, 'utf8')); + const packageJson = JSON.parse(fs.readFileSync(fullPath, "utf8")); const oldVersion = packageJson.version; packageJson.version = newVersion; - + // Update workspace dependencies in root package.json - if (packagePath === 'package.json' && packageJson.dependencies) { - Object.keys(packageJson.dependencies).forEach(dep => { - if (dep.startsWith('@modelcontextprotocol/inspector-')) { + if (packagePath === "package.json" && packageJson.dependencies) { + Object.keys(packageJson.dependencies).forEach((dep) => { + if (dep.startsWith("@modelcontextprotocol/inspector-")) { packageJson.dependencies[dep] = `^${newVersion}`; } }); } - - fs.writeFileSync(fullPath, JSON.stringify(packageJson, null, 2) + '\n'); + + fs.writeFileSync(fullPath, JSON.stringify(packageJson, null, 2) + "\n"); updatedFiles.push(packagePath); - console.log(`āœ… Updated ${packagePath} from ${oldVersion} to ${newVersion}`); + console.log( + `āœ… Updated ${packagePath} from ${oldVersion} to ${newVersion}`, + ); } catch (error) { console.error(`āŒ Failed to update ${packagePath}:`, error.message); process.exit(1); } }); -console.log('\nšŸ“ Summary:'); +console.log("\nšŸ“ Summary:"); console.log(`Updated ${updatedFiles.length} files to version ${newVersion}`); // Update package-lock.json -console.log('\nšŸ”’ Updating package-lock.json...'); +console.log("\nšŸ”’ Updating package-lock.json..."); try { - execSync('npm install', { stdio: 'inherit' }); - console.log('āœ… package-lock.json updated successfully'); + execSync("npm install", { stdio: "inherit" }); + console.log("āœ… package-lock.json updated successfully"); } catch (error) { - console.error('āŒ Failed to update package-lock.json:', error.message); + console.error("āŒ Failed to update package-lock.json:", error.message); console.error('Please run "npm install" manually'); process.exit(1); } -console.log('\n✨ Version update complete!'); -console.log('\nNext steps:'); -console.log('1. Review the changes: git diff'); -console.log('2. Commit the changes: git add -A && git commit -m "chore: bump version to ' + newVersion + '"'); -console.log('3. Create a git tag: git tag v' + newVersion); -console.log('4. Push changes and tag: git push && git push --tags'); \ No newline at end of file +console.log("\n✨ Version update complete!"); +console.log("\nNext steps:"); +console.log("1. Review the changes: git diff"); +console.log( + '2. Commit the changes: git add -A && git commit -m "chore: bump version to ' + + newVersion + + '"', +); +console.log("3. Create a git tag: git tag v" + newVersion); +console.log("4. Push changes and tag: git push && git push --tags");