feat: migrate repo releases to manual release-please (#293)
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import { mkdtempSync, rmSync, writeFileSync } from "fs"
|
||||
import os from "os"
|
||||
import path from "path"
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { convertClaudeToKiro, transformContentForKiro } from "../src/converters/claude-to-kiro"
|
||||
import { parseFrontmatter } from "../src/utils/frontmatter"
|
||||
@@ -274,7 +277,7 @@ describe("convertClaudeToKiro", () => {
|
||||
expect(warnings.some((w) => w.includes("Kiro"))).toBe(true)
|
||||
})
|
||||
|
||||
test("steering file not generated when CLAUDE.md missing", () => {
|
||||
test("steering file not generated when repo instruction files are missing", () => {
|
||||
const plugin: ClaudePlugin = {
|
||||
...fixturePlugin,
|
||||
root: "/tmp/nonexistent-plugin-dir",
|
||||
@@ -287,6 +290,27 @@ describe("convertClaudeToKiro", () => {
|
||||
expect(bundle.steeringFiles).toHaveLength(0)
|
||||
})
|
||||
|
||||
test("steering file prefers AGENTS.md over CLAUDE.md", () => {
|
||||
const root = mkdtempSync(path.join(os.tmpdir(), "kiro-steering-"))
|
||||
writeFileSync(path.join(root, "AGENTS.md"), "# AGENTS\nUse AGENTS instructions.")
|
||||
writeFileSync(path.join(root, "CLAUDE.md"), "# CLAUDE\nUse CLAUDE instructions.")
|
||||
|
||||
const plugin: ClaudePlugin = {
|
||||
...fixturePlugin,
|
||||
root,
|
||||
agents: [],
|
||||
commands: [],
|
||||
skills: [],
|
||||
}
|
||||
|
||||
const bundle = convertClaudeToKiro(plugin, defaultOptions)
|
||||
rmSync(root, { recursive: true, force: true })
|
||||
|
||||
expect(bundle.steeringFiles).toHaveLength(1)
|
||||
expect(bundle.steeringFiles[0].content).toContain("Use AGENTS instructions.")
|
||||
expect(bundle.steeringFiles[0].content).not.toContain("Use CLAUDE instructions.")
|
||||
})
|
||||
|
||||
test("name normalization handles various inputs", () => {
|
||||
const plugin: ClaudePlugin = {
|
||||
...fixturePlugin,
|
||||
|
||||
102
tests/release-components.test.ts
Normal file
102
tests/release-components.test.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import {
|
||||
applyOverride,
|
||||
bumpVersion,
|
||||
detectComponentsFromFiles,
|
||||
inferBumpFromIntent,
|
||||
parseReleaseIntent,
|
||||
resolveComponentWarnings,
|
||||
} from "../src/release/components"
|
||||
|
||||
describe("release component detection", () => {
|
||||
test("maps plugin-only changes to the matching plugin component", () => {
|
||||
const components = detectComponentsFromFiles([
|
||||
"plugins/compound-engineering/skills/ce-plan/SKILL.md",
|
||||
])
|
||||
|
||||
expect(components.get("compound-engineering")).toEqual([
|
||||
"plugins/compound-engineering/skills/ce-plan/SKILL.md",
|
||||
])
|
||||
expect(components.get("cli")).toEqual([])
|
||||
expect(components.get("coding-tutor")).toEqual([])
|
||||
expect(components.get("marketplace")).toEqual([])
|
||||
})
|
||||
|
||||
test("maps cli and plugin changes independently", () => {
|
||||
const components = detectComponentsFromFiles([
|
||||
"src/commands/install.ts",
|
||||
"plugins/coding-tutor/.claude-plugin/plugin.json",
|
||||
])
|
||||
|
||||
expect(components.get("cli")).toEqual(["src/commands/install.ts"])
|
||||
expect(components.get("coding-tutor")).toEqual([
|
||||
"plugins/coding-tutor/.claude-plugin/plugin.json",
|
||||
])
|
||||
})
|
||||
|
||||
test("maps marketplace metadata without bumping plugin components", () => {
|
||||
const components = detectComponentsFromFiles([".claude-plugin/marketplace.json"])
|
||||
expect(components.get("marketplace")).toEqual([".claude-plugin/marketplace.json"])
|
||||
expect(components.get("compound-engineering")).toEqual([])
|
||||
expect(components.get("coding-tutor")).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe("release intent parsing", () => {
|
||||
test("parses conventional titles with optional scope and breaking marker", () => {
|
||||
const parsed = parseReleaseIntent("feat(coding-tutor)!: add tutor reset flow")
|
||||
expect(parsed.type).toBe("feat")
|
||||
expect(parsed.scope).toBe("coding-tutor")
|
||||
expect(parsed.breaking).toBe(true)
|
||||
expect(parsed.description).toBe("add tutor reset flow")
|
||||
})
|
||||
|
||||
test("supports conventional titles without scope", () => {
|
||||
const parsed = parseReleaseIntent("fix: adjust ce:plan-beta wording")
|
||||
expect(parsed.type).toBe("fix")
|
||||
expect(parsed.scope).toBeNull()
|
||||
expect(parsed.breaking).toBe(false)
|
||||
})
|
||||
|
||||
test("infers bump levels from parsed intent", () => {
|
||||
expect(inferBumpFromIntent(parseReleaseIntent("feat: add release preview"))).toBe("minor")
|
||||
expect(inferBumpFromIntent(parseReleaseIntent("fix: correct preview output"))).toBe("patch")
|
||||
expect(inferBumpFromIntent(parseReleaseIntent("docs: update requirements"))).toBeNull()
|
||||
expect(inferBumpFromIntent(parseReleaseIntent("refactor!: break compatibility"))).toBe("major")
|
||||
})
|
||||
})
|
||||
|
||||
describe("override handling", () => {
|
||||
test("keeps inferred bump when override is auto", () => {
|
||||
expect(applyOverride("patch", "auto")).toBe("patch")
|
||||
})
|
||||
|
||||
test("promotes inferred bump when override is explicit", () => {
|
||||
expect(applyOverride("patch", "minor")).toBe("minor")
|
||||
expect(applyOverride(null, "major")).toBe("major")
|
||||
})
|
||||
|
||||
test("increments semver versions", () => {
|
||||
expect(bumpVersion("2.42.0", "patch")).toBe("2.42.1")
|
||||
expect(bumpVersion("2.42.0", "minor")).toBe("2.43.0")
|
||||
expect(bumpVersion("2.42.0", "major")).toBe("3.0.0")
|
||||
})
|
||||
})
|
||||
|
||||
describe("scope mismatch warnings", () => {
|
||||
test("does not require scope when omitted", () => {
|
||||
const warnings = resolveComponentWarnings(
|
||||
parseReleaseIntent("fix: update ce plan copy"),
|
||||
["compound-engineering"],
|
||||
)
|
||||
expect(warnings).toEqual([])
|
||||
})
|
||||
|
||||
test("warns when explicit scope contradicts detected files", () => {
|
||||
const warnings = resolveComponentWarnings(
|
||||
parseReleaseIntent("fix(cli): update coding tutor text"),
|
||||
["coding-tutor"],
|
||||
)
|
||||
expect(warnings[0]).toContain('Optional scope "cli" does not match')
|
||||
})
|
||||
})
|
||||
23
tests/release-metadata.test.ts
Normal file
23
tests/release-metadata.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { buildCompoundEngineeringDescription, renderChangelogEntry } from "../src/release/metadata"
|
||||
|
||||
describe("release metadata", () => {
|
||||
test("builds the current compound-engineering manifest description from repo counts", async () => {
|
||||
const description = await buildCompoundEngineeringDescription(process.cwd())
|
||||
expect(description).toBe(
|
||||
"AI-powered development tools. 29 agents, 44 skills, 1 MCP server for code review, research, design, and workflow automation.",
|
||||
)
|
||||
})
|
||||
|
||||
test("renders root changelog entries with component-version headings", () => {
|
||||
const entry = renderChangelogEntry("compound-engineering", "2.43.0", "2026-04-10", {
|
||||
Features: ["Add release preview"],
|
||||
Fixes: ["Correct changelog rendering"],
|
||||
})
|
||||
|
||||
expect(entry).toContain("## compound-engineering v2.43.0 - 2026-04-10")
|
||||
expect(entry).toContain("### Features")
|
||||
expect(entry).toContain("- Add release preview")
|
||||
expect(entry).toContain("### Fixes")
|
||||
})
|
||||
})
|
||||
41
tests/release-preview.test.ts
Normal file
41
tests/release-preview.test.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { buildReleasePreview } from "../src/release/components"
|
||||
|
||||
describe("release preview", () => {
|
||||
test("uses changed files to determine affected components and next versions", async () => {
|
||||
const preview = await buildReleasePreview({
|
||||
title: "fix: adjust ce:plan-beta wording",
|
||||
files: ["plugins/compound-engineering/skills/ce-plan-beta/SKILL.md"],
|
||||
})
|
||||
|
||||
expect(preview.components).toHaveLength(1)
|
||||
expect(preview.components[0].component).toBe("compound-engineering")
|
||||
expect(preview.components[0].inferredBump).toBe("patch")
|
||||
expect(preview.components[0].nextVersion).toBe("2.42.1")
|
||||
})
|
||||
|
||||
test("supports per-component overrides without affecting unrelated components", async () => {
|
||||
const preview = await buildReleasePreview({
|
||||
title: "fix: update coding tutor prompts",
|
||||
files: ["plugins/coding-tutor/README.md"],
|
||||
overrides: {
|
||||
"coding-tutor": "minor",
|
||||
},
|
||||
})
|
||||
|
||||
expect(preview.components).toHaveLength(1)
|
||||
expect(preview.components[0].component).toBe("coding-tutor")
|
||||
expect(preview.components[0].inferredBump).toBe("patch")
|
||||
expect(preview.components[0].effectiveBump).toBe("minor")
|
||||
expect(preview.components[0].nextVersion).toBe("1.3.0")
|
||||
})
|
||||
|
||||
test("docs-only changes remain non-releasable by default", async () => {
|
||||
const preview = await buildReleasePreview({
|
||||
title: "docs: update release planning notes",
|
||||
files: ["docs/plans/2026-03-17-001-feat-release-automation-migration-beta-plan.md"],
|
||||
})
|
||||
|
||||
expect(preview.components).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user