diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 2c2b3fe..1ba26b5 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -44,6 +44,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} config-file: .github/release-please-config.json manifest-file: .github/.release-please-manifest.json + skip-labeling: true publish-cli: needs: release-pr diff --git a/plugins/compound-engineering/.cursor-plugin/plugin.json b/plugins/compound-engineering/.cursor-plugin/plugin.json index 02c2c2c..88bcd27 100644 --- a/plugins/compound-engineering/.cursor-plugin/plugin.json +++ b/plugins/compound-engineering/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "compound-engineering", "displayName": "Compound Engineering", - "version": "2.33.0", + "version": "2.42.0", "description": "AI-powered development tools. 29 agents, 44 skills, 1 MCP server for code review, research, design, and workflow automation.", "author": { "name": "Kieran Klaassen", diff --git a/src/release/metadata.ts b/src/release/metadata.ts index 745300c..d15a1d5 100644 --- a/src/release/metadata.ts +++ b/src/release/metadata.ts @@ -41,6 +41,13 @@ export type MetadataSyncResult = { updates: FileUpdate[] } +function resolveExpectedVersion( + explicitVersion: string | undefined, + fallbackVersion: string, +): string { + return explicitVersion ?? fallbackVersion +} + export async function countMarkdownFiles(root: string): Promise { const entries = await fs.readdir(root, { withFileTypes: true }) let total = 0 @@ -110,10 +117,18 @@ export async function syncReleaseMetadata(options: SyncOptions = {}): Promise(codingTutorClaudePath) const codingTutorCursor = await readJson(codingTutorCursorPath) const marketplaceClaude = await readJson(marketplaceClaudePath) + const expectedCompoundVersion = resolveExpectedVersion( + versions["compound-engineering"], + compoundClaude.version, + ) + const expectedCodingTutorVersion = resolveExpectedVersion( + versions["coding-tutor"], + codingTutorClaude.version, + ) let changed = false - if (versions["compound-engineering"] && compoundClaude.version !== versions["compound-engineering"]) { - compoundClaude.version = versions["compound-engineering"] + if (compoundClaude.version !== expectedCompoundVersion) { + compoundClaude.version = expectedCompoundVersion changed = true } if (compoundClaude.description !== compoundDescription) { @@ -124,8 +139,8 @@ export async function syncReleaseMetadata(options: SyncOptions = {}): Promise { + for (const root of tempRoots.splice(0, tempRoots.length)) { + await Bun.$`rm -rf ${root}`.quiet() + } +}) + +async function makeFixtureRoot(): Promise { + const root = await mkdtemp(path.join(os.tmpdir(), "release-metadata-")) + tempRoots.push(root) + + await mkdir(path.join(root, "plugins", "compound-engineering", "agents", "review"), { + recursive: true, + }) + await mkdir(path.join(root, "plugins", "compound-engineering", "skills", "ce-plan"), { + recursive: true, + }) + await mkdir(path.join(root, "plugins", "compound-engineering", ".claude-plugin"), { + recursive: true, + }) + await mkdir(path.join(root, "plugins", "compound-engineering", ".cursor-plugin"), { + recursive: true, + }) + await mkdir(path.join(root, "plugins", "coding-tutor", ".claude-plugin"), { + recursive: true, + }) + await mkdir(path.join(root, "plugins", "coding-tutor", ".cursor-plugin"), { + recursive: true, + }) + await mkdir(path.join(root, ".claude-plugin"), { recursive: true }) + + await writeFile( + path.join(root, "plugins", "compound-engineering", "agents", "review", "agent.md"), + "# Review Agent\n", + ) + await writeFile( + path.join(root, "plugins", "compound-engineering", "skills", "ce-plan", "SKILL.md"), + "# ce:plan\n", + ) + await writeFile( + path.join(root, "plugins", "compound-engineering", ".mcp.json"), + JSON.stringify({ mcpServers: { context7: { command: "ctx7" } } }, null, 2), + ) + await writeFile( + path.join(root, "plugins", "compound-engineering", ".claude-plugin", "plugin.json"), + JSON.stringify({ version: "2.42.0", description: "old" }, null, 2), + ) + await writeFile( + path.join(root, "plugins", "compound-engineering", ".cursor-plugin", "plugin.json"), + JSON.stringify({ version: "2.33.0", description: "old" }, null, 2), + ) + await writeFile( + path.join(root, "plugins", "coding-tutor", ".claude-plugin", "plugin.json"), + JSON.stringify({ version: "1.2.1" }, null, 2), + ) + await writeFile( + path.join(root, "plugins", "coding-tutor", ".cursor-plugin", "plugin.json"), + JSON.stringify({ version: "1.2.1" }, null, 2), + ) + await writeFile( + path.join(root, ".claude-plugin", "marketplace.json"), + JSON.stringify( + { + metadata: { version: "1.0.0", description: "marketplace" }, + plugins: [ + { name: "compound-engineering", version: "2.41.0", description: "old" }, + { name: "coding-tutor", version: "1.2.0", description: "old" }, + ], + }, + null, + 2, + ), + ) + + return root +} describe("release metadata", () => { test("builds the current compound-engineering manifest description from repo counts", async () => { @@ -8,4 +89,13 @@ describe("release metadata", () => { "AI-powered development tools. 29 agents, 44 skills, 1 MCP server for code review, research, design, and workflow automation.", ) }) + + test("detects cross-surface version drift even without explicit override versions", async () => { + const root = await makeFixtureRoot() + const result = await syncReleaseMetadata({ root, write: false }) + const changedPaths = result.updates.filter((update) => update.changed).map((update) => update.path) + + expect(changedPaths).toContain(path.join(root, "plugins", "compound-engineering", ".cursor-plugin", "plugin.json")) + expect(changedPaths).toContain(path.join(root, ".claude-plugin", "marketplace.json")) + }) })