Skip to main content
Glama
release.jsโ€ข7.72 kB
#!/usr/bin/env node import { execSync } from 'child_process'; import { readFileSync, writeFileSync } from 'fs'; import { createHash } from 'crypto'; const versionType = process.argv[2]; if (!versionType) { console.error('Usage: npm run release-custom <major|minor|patch|version>'); console.error('Examples:'); console.error(' npm run release-custom patch'); console.error(' npm run release-custom minor'); console.error(' npm run release-custom 2.3.3'); process.exit(1); } function calculateSHA256(filePath) { try { const fileBuffer = readFileSync(filePath); const hashSum = createHash('sha256'); hashSum.update(fileBuffer); return hashSum.digest('hex'); } catch (error) { console.warn(`โš ๏ธ Could not calculate SHA256 for ${filePath}: ${error.message}`); return null; } } function incrementVersion(currentVersion, type) { // Clean the version string and split const cleanVersion = currentVersion.replace(/^v/, ''); // Remove 'v' prefix if present const parts = cleanVersion.split('.'); if (parts.length !== 3) { throw new Error(`Invalid version format: ${currentVersion}. Expected format: x.y.z`); } const [major, minor, patch] = parts.map(part => { const num = parseInt(part, 10); if (isNaN(num)) { throw new Error(`Invalid version part: ${part} in version ${currentVersion}`); } return num; }); console.log(`๐Ÿ” Current version parts: major=${major}, minor=${minor}, patch=${patch}`); switch (type) { case 'major': return `${major + 1}.0.0`; case 'minor': return `${major}.${minor + 1}.0`; case 'patch': return `${major}.${minor}.${patch + 1}`; default: // Validate specific version format if (!/^\d+\.\d+\.\d+$/.test(type)) { throw new Error(`Invalid version format: ${type}. Use 'major', 'minor', 'patch', or a version like '1.2.3'`); } return type; } } try { // Read current version const pkg = JSON.parse(readFileSync('package.json', 'utf8')); const currentVersion = pkg.version; const newVersion = incrementVersion(currentVersion, versionType); console.log(`๐Ÿ“ฆ Updating version from ${currentVersion} to ${newVersion}`); // Update package.json version pkg.version = newVersion; writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); // Update package-lock.json version console.log('๐Ÿ”’ Updating package-lock.json...'); execSync('npm install --package-lock-only', { stdio: 'inherit' }); // Build project console.log('๐Ÿ”จ Building project...'); execSync('npm run build', { stdio: 'inherit' }); // Update manifest versions console.log('๐Ÿ“ Updating manifest files...'); const updateManifest = (file) => { const manifest = JSON.parse(readFileSync(file, 'utf8')); manifest.version = newVersion; writeFileSync(file, JSON.stringify(manifest, null, 2) + '\n'); }; updateManifest('manifest-full.json'); updateManifest('manifest-minimal.json'); updateManifest('manifest-code.json'); // Build mcpb packages locally to calculate SHA256 hashes console.log('๐Ÿ“ฆ Building mcpb packages for SHA256 calculation...'); // Check if mcpb is installed try { execSync('which mcpb', { stdio: 'pipe' }); } catch { console.log('โš ๏ธ mcpb not found, installing globally...'); execSync('npm install -g @anthropic-ai/mcpb', { stdio: 'inherit' }); } // Install production dependencies for packaging console.log('๐Ÿ“ฆ Installing production dependencies...'); execSync('npm ci --omit=dev', { stdio: 'inherit' }); // Package minimal version console.log('๐Ÿ“ฆ Packaging minimal version...'); execSync('cp manifest-minimal.json manifest.json', { stdio: 'inherit' }); execSync('mcpb pack', { stdio: 'inherit' }); const currentDir = execSync('basename "$PWD"', { encoding: 'utf8' }).trim(); execSync(`mv "${currentDir}.mcpb" "postman-mcp-server-minimal.mcpb"`, { stdio: 'inherit' }); // Package full version console.log('๐Ÿ“ฆ Packaging full version...'); execSync('cp manifest-full.json manifest.json', { stdio: 'inherit' }); execSync('mcpb pack', { stdio: 'inherit' }); execSync(`mv "${currentDir}.mcpb" "postman-mcp-server-full.mcpb"`, { stdio: 'inherit' }); // Package code version console.log('๐Ÿ“ฆ Packaging code version...'); execSync('cp manifest-code.json manifest.json', { stdio: 'inherit' }); execSync('mcpb pack', { stdio: 'inherit' }); execSync(`mv "${currentDir}.mcpb" "postman-mcp-server-code.mcpb"`, { stdio: 'inherit' }); // Restore manifest.json (optional, or delete it) execSync('rm manifest.json', { stdio: 'inherit' }); // Reinstall all dependencies console.log('๐Ÿ“ฆ Reinstalling all dependencies...'); execSync('npm ci', { stdio: 'inherit' }); // Update server.json with versions and SHA256 hashes console.log('๐Ÿ“ Updating server.json...'); const serverJson = JSON.parse(readFileSync('server.json', 'utf8')); serverJson.version = newVersion; // Update the version in the npm package entry if (serverJson.packages && Array.isArray(serverJson.packages)) { const npmPackage = serverJson.packages.find(pkg => pkg.registryType === 'npm'); if (npmPackage) { npmPackage.version = newVersion; } // Update mcpb packages with new identifiers and SHA256 hashes console.log('๐Ÿ” Calculating SHA256 hashes for mcpb packages...'); const mcpbFiles = [ { name: 'postman-mcp-server-minimal.mcpb', path: 'postman-mcp-server-minimal.mcpb' }, { name: 'postman-mcp-server-full.mcpb', path: 'postman-mcp-server-full.mcpb' }, { name: 'postman-mcp-server-code.mcpb', path: 'postman-mcp-server-code.mcpb' } ]; const mcpbPackages = serverJson.packages.filter(pkg => pkg.registryType === 'mcpb'); mcpbFiles.forEach((file, index) => { const mcpbPackage = mcpbPackages[index]; if (mcpbPackage) { // Update identifier URL with new version mcpbPackage.identifier = `https://github.com/postmanlabs/postman-mcp-server/releases/download/v${newVersion}/${file.name}`; // Calculate and update SHA256 hash const sha256 = calculateSHA256(file.path); if (sha256) { mcpbPackage.fileSha256 = sha256; console.log(` โœ“ ${file.name}: ${sha256}`); } else { console.warn(` โš ๏ธ Could not calculate SHA256 for ${file.name}`); } } }); } writeFileSync('server.json', JSON.stringify(serverJson, null, 2) + '\n'); // Clean up mcpb files (they'll be rebuilt by GitHub Action) console.log('๐Ÿงน Cleaning up local mcpb packages...'); execSync('rm -f postman-mcp-server-minimal.mcpb postman-mcp-server-full.mcpb postman-mcp-server-code.mcpb', { stdio: 'inherit' }); // Commit and tag console.log('๐Ÿ“ค Committing and tagging...'); execSync('git add .', { stdio: 'inherit' }); execSync(`git commit -m "chore: v${newVersion}"`, { stdio: 'inherit' }); execSync(`git tag -a v${newVersion} -m "v${newVersion}"`, { stdio: 'inherit' }); console.log(`โœ… Released version ${newVersion}`); console.log(`๐Ÿš€ Push with: git push origin main --tags`); } catch (error) { console.error('โŒ Release failed:', error.message); process.exit(1); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/postmanlabs/postman-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server