Skip to main content
Glama
version-consistency.test.tsβ€’3.63 kB
/** * Version consistency validation tests * Ensures package.json version matches CHANGELOG and other version references */ import { describe, it, expect } from 'vitest'; import { readFileSync } from 'fs'; import { resolve } from 'path'; describe('Version Consistency Validation', () => { const projectRoot = resolve(__dirname, '../..'); it('should have consistent version across package.json and CHANGELOG.md', () => { // Read package.json version const packageJsonPath = resolve(projectRoot, 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); const packageVersion = packageJson.version; // Read CHANGELOG.md content const changelogPath = resolve(projectRoot, 'CHANGELOG.md'); const changelogContent = readFileSync(changelogPath, 'utf-8'); // Extract the latest version from CHANGELOG (first version entry) const versionMatch = changelogContent.match(/^## \[([^\]]+)\]/m); expect(versionMatch, 'Could not find version in CHANGELOG.md').toBeTruthy(); const changelogVersion = versionMatch![1]; // If it's "Unreleased", skip validation if (changelogVersion === 'Unreleased') { return; } expect(packageVersion).toBe( changelogVersion, `Package.json version (${packageVersion}) should match CHANGELOG.md version (${changelogVersion})` ); }); it('should have valid semver format in package.json', () => { const packageJsonPath = resolve(projectRoot, 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); const version = packageJson.version; // Basic semver validation (major.minor.patch) const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/; expect(version).toMatch( semverRegex, `Version ${version} should follow semantic versioning format` ); }); it('should have version comparison links in correct format in CHANGELOG', () => { const changelogPath = resolve(projectRoot, 'CHANGELOG.md'); const changelogContent = readFileSync(changelogPath, 'utf-8'); // Look for version comparison links at the bottom const linkPattern = /\[([^\]]+)\]: https:\/\/github\.com\/kesslerio\/attio-mcp-server\/compare\/([^.]+)\.\.\.([^.]+)/g; const links = [...changelogContent.matchAll(linkPattern)]; if (links.length > 0) { links.forEach((match) => { const [, version, fromTag, toTag] = match; // Skip unreleased links if (version === 'Unreleased') return; // Version should match the toTag (without 'v' prefix) const expectedToTag = toTag.startsWith('v') ? toTag.slice(1) : toTag; expect(version).toBe( expectedToTag, `Version ${version} should match tag ${expectedToTag} in comparison link` ); }); } }); it('should have required package.json fields for release', () => { const packageJsonPath = resolve(projectRoot, 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); // Validate required fields for npm release expect(packageJson.name).toBeTruthy('Package must have a name'); expect(packageJson.version).toBeTruthy('Package must have a version'); expect(packageJson.description).toBeTruthy( 'Package must have a description' ); expect(packageJson.author).toBeTruthy('Package must have an author'); expect(packageJson.license).toBeTruthy('Package must have a license'); expect(packageJson.main || packageJson.exports).toBeTruthy( 'Package must have main entry point' ); }); });

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/kesslerio/attio-mcp-server'

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