mirror of
https://github.com/svnscha/mcp-windbg.git
synced 2026-10-17 04:41:56 +08:00
7c55ac325f
Separate the MCP server, four debugging skills, and crash-analyst agent into independently installable plugins. Document installation and migration, support existing MCP connections, and validate every marketplace version.
145 lines
6.2 KiB
PowerShell
145 lines
6.2 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
<#
|
|
.SYNOPSIS
|
|
Checks that every version in the repository, and the CHANGELOG entry, agree
|
|
|
|
.DESCRIPTION
|
|
Extracts the version from pyproject.toml, server.json (top level and package),
|
|
.release-please-manifest.json, the Claude plugin manifest, every marketplace entry and the
|
|
server version pinned in the plugin's .mcp.json, and checks they all match. Also checks that
|
|
CHANGELOG.md's top heading names that version and has an entry underneath it.
|
|
|
|
Run as a gate before release-please creates a tag: everything it asserts is something that
|
|
cannot be fixed after a release without publishing a second one.
|
|
|
|
.EXAMPLE
|
|
.\check-version-consistency.ps1
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param()
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
try {
|
|
Write-Host "Checking version consistency..." -ForegroundColor Cyan
|
|
|
|
# Extract version from pyproject.toml
|
|
if (-not (Test-Path "pyproject.toml")) {
|
|
throw "pyproject.toml not found in current directory"
|
|
}
|
|
|
|
$pyprojectMatch = Select-String -Path "pyproject.toml" -Pattern 'version = "([^"]+)"'
|
|
if (-not $pyprojectMatch) {
|
|
throw "Could not find version in pyproject.toml"
|
|
}
|
|
$PYPROJECT_VERSION = $pyprojectMatch.Matches[0].Groups[1].Value
|
|
Write-Host "INFO: pyproject.toml version: $PYPROJECT_VERSION" -ForegroundColor Green
|
|
|
|
# Extract version from server.json
|
|
if (-not (Test-Path "server.json")) {
|
|
throw "server.json not found in current directory"
|
|
}
|
|
|
|
$serverJsonContent = Get-Content "server.json" -Raw | ConvertFrom-Json
|
|
$SERVER_VERSION = $serverJsonContent.version
|
|
$PACKAGE_VERSION = $serverJsonContent.packages[0].version
|
|
Write-Host "INFO: server.json version: $SERVER_VERSION" -ForegroundColor Green
|
|
Write-Host "INFO: server.json package version: $PACKAGE_VERSION" -ForegroundColor Green
|
|
|
|
# Extract version from CHANGELOG.md
|
|
if (-not (Test-Path "CHANGELOG.md")) {
|
|
throw "CHANGELOG.md not found in current directory"
|
|
}
|
|
|
|
$changelogMatch = Select-String -Path "CHANGELOG.md" -Pattern '## \[([^\]]+)\]' | Select-Object -First 1
|
|
if (-not $changelogMatch) {
|
|
throw "Could not find version in CHANGELOG.md"
|
|
}
|
|
$CHANGELOG_VERSION = $changelogMatch.Matches[0].Groups[1].Value
|
|
Write-Host "INFO: CHANGELOG.md version: $CHANGELOG_VERSION" -ForegroundColor Green
|
|
|
|
# A heading on its own still matches the version but leaves release-notes with nothing to
|
|
# publish, so read what sits under it, up to the next heading. LineNumber is 1-based and the
|
|
# array is 0-based, so indexing with it starts on the line after the heading.
|
|
$changelogLines = Get-Content "CHANGELOG.md"
|
|
$entryBody = @()
|
|
for ($i = $changelogMatch.LineNumber; $i -lt $changelogLines.Count; $i++) {
|
|
if ($changelogLines[$i].StartsWith("## [")) { break }
|
|
$entryBody += $changelogLines[$i]
|
|
}
|
|
$CHANGELOG_EMPTY = -not ($entryBody | Where-Object { $_.Trim() })
|
|
|
|
# The version release-please itself tracks. If this drifts from pyproject.toml the next
|
|
# release is computed from the wrong base.
|
|
$MANIFEST_VERSION = (Get-Content ".release-please-manifest.json" -Raw | ConvertFrom-Json).'.'
|
|
Write-Host "INFO: .release-please-manifest.json version: $MANIFEST_VERSION" -ForegroundColor Green
|
|
|
|
# Extract versions from the Claude plugin + marketplace manifests. These are
|
|
# kept in step by release-please extra-files entries; checking them here is
|
|
# what catches an entry that silently stopped matching.
|
|
$PLUGIN_VERSION = (Get-Content "plugins/mcp-windbg/.claude-plugin/plugin.json" -Raw | ConvertFrom-Json).version
|
|
$marketplacePlugins = (Get-Content ".claude-plugin/marketplace.json" -Raw | ConvertFrom-Json).plugins
|
|
$mcpArgs = (Get-Content "plugins/mcp-windbg/.mcp.json" -Raw | ConvertFrom-Json).mcpServers.'mcp-windbg'.args
|
|
$PINNED_VERSION = ($mcpArgs[0] -split '@')[-1]
|
|
Write-Host "INFO: plugin.json version: $PLUGIN_VERSION" -ForegroundColor Green
|
|
foreach ($plugin in $marketplacePlugins) {
|
|
Write-Host "INFO: marketplace $($plugin.name): $($plugin.version)" -ForegroundColor Green
|
|
}
|
|
Write-Host "INFO: plugin .mcp.json pinned server: $PINNED_VERSION" -ForegroundColor Green
|
|
|
|
# Check if all versions match
|
|
$errors = @()
|
|
|
|
if ($PYPROJECT_VERSION -ne $PLUGIN_VERSION) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != plugin.json ($PLUGIN_VERSION)"
|
|
}
|
|
|
|
foreach ($plugin in $marketplacePlugins) {
|
|
if ($PYPROJECT_VERSION -ne $plugin.version) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != marketplace $($plugin.name) ($($plugin.version))"
|
|
}
|
|
}
|
|
|
|
if ($PYPROJECT_VERSION -ne $PINNED_VERSION) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != plugin .mcp.json pin ($PINNED_VERSION)"
|
|
}
|
|
|
|
if ($PYPROJECT_VERSION -ne $SERVER_VERSION) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != server.json ($SERVER_VERSION)"
|
|
}
|
|
|
|
if ($PYPROJECT_VERSION -ne $PACKAGE_VERSION) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != server.json package ($PACKAGE_VERSION)"
|
|
}
|
|
|
|
if ($PYPROJECT_VERSION -ne $CHANGELOG_VERSION) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != CHANGELOG.md ($CHANGELOG_VERSION)"
|
|
}
|
|
|
|
if ($PYPROJECT_VERSION -ne $MANIFEST_VERSION) {
|
|
$errors += "Version mismatch: pyproject.toml ($PYPROJECT_VERSION) != .release-please-manifest.json ($MANIFEST_VERSION)"
|
|
}
|
|
|
|
if ($CHANGELOG_EMPTY) {
|
|
$errors += "CHANGELOG.md has a '## [$CHANGELOG_VERSION]' heading with nothing under it - the release notes would be empty"
|
|
}
|
|
|
|
if ($errors.Count -gt 0) {
|
|
# Not $error: that is a read-only PowerShell automatic variable, and
|
|
# assigning it threw before any mismatch could be reported.
|
|
foreach ($mismatch in $errors) {
|
|
Write-Host "ERROR: $mismatch" -ForegroundColor Red
|
|
}
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "`nAll versions are consistent: $PYPROJECT_VERSION" -ForegroundColor Green
|
|
exit 0
|
|
}
|
|
catch {
|
|
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
|
exit 1
|
|
}
|