chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bun
|
||||
import { buildReleasePreview } from "../../src/release/components"
|
||||
import type { BumpOverride, ReleaseComponent } from "../../src/release/types"
|
||||
|
||||
function parseArgs(argv: string[]): {
|
||||
title: string
|
||||
files: string[]
|
||||
overrides: Partial<Record<ReleaseComponent, BumpOverride>>
|
||||
json: boolean
|
||||
} {
|
||||
let title = ""
|
||||
const files: string[] = []
|
||||
const overrides: Partial<Record<ReleaseComponent, BumpOverride>> = {}
|
||||
let json = false
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index]
|
||||
if (arg === "--title") {
|
||||
title = argv[index + 1] ?? ""
|
||||
index += 1
|
||||
continue
|
||||
}
|
||||
if (arg === "--file") {
|
||||
const file = argv[index + 1]
|
||||
if (file) files.push(file)
|
||||
index += 1
|
||||
continue
|
||||
}
|
||||
if (arg === "--override") {
|
||||
const raw = argv[index + 1] ?? ""
|
||||
const [component, value] = raw.split("=")
|
||||
if (component && value) {
|
||||
overrides[component as ReleaseComponent] = value as BumpOverride
|
||||
}
|
||||
index += 1
|
||||
continue
|
||||
}
|
||||
if (arg === "--json") {
|
||||
json = true
|
||||
}
|
||||
}
|
||||
|
||||
return { title, files, overrides, json }
|
||||
}
|
||||
|
||||
function formatPreview(preview: Awaited<ReturnType<typeof buildReleasePreview>>): string {
|
||||
const lines: string[] = []
|
||||
lines.push(`Release intent: ${preview.intent.raw || "(missing title)"}`)
|
||||
if (preview.intent.type) {
|
||||
lines.push(
|
||||
`Parsed as: type=${preview.intent.type}${preview.intent.scope ? `, scope=${preview.intent.scope}` : ""}${preview.intent.breaking ? ", breaking=true" : ""}`,
|
||||
)
|
||||
}
|
||||
|
||||
if (preview.warnings.length > 0) {
|
||||
lines.push("", "Warnings:")
|
||||
for (const warning of preview.warnings) {
|
||||
lines.push(`- ${warning}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (preview.components.length === 0) {
|
||||
lines.push("", "No releasable components detected.")
|
||||
return lines.join("\n")
|
||||
}
|
||||
|
||||
lines.push("", "Components:")
|
||||
for (const component of preview.components) {
|
||||
lines.push(`- ${component.component}`)
|
||||
lines.push(` current: ${component.currentVersion}`)
|
||||
lines.push(` inferred bump: ${component.inferredBump ?? "none"}`)
|
||||
lines.push(` override: ${component.override}`)
|
||||
lines.push(` effective bump: ${component.effectiveBump ?? "none"}`)
|
||||
lines.push(` next: ${component.nextVersion ?? "unchanged"}`)
|
||||
lines.push(` files: ${component.files.join(", ")}`)
|
||||
}
|
||||
|
||||
return lines.join("\n")
|
||||
}
|
||||
|
||||
const args = parseArgs(process.argv.slice(2))
|
||||
const preview = await buildReleasePreview({
|
||||
title: args.title,
|
||||
files: args.files,
|
||||
overrides: args.overrides,
|
||||
})
|
||||
|
||||
if (args.json) {
|
||||
console.log(JSON.stringify(preview, null, 2))
|
||||
} else {
|
||||
console.log(formatPreview(preview))
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bun
|
||||
import { syncReleaseMetadata } from "../../src/release/metadata"
|
||||
|
||||
const write = process.argv.includes("--write")
|
||||
const versionArgs = process.argv
|
||||
.slice(2)
|
||||
.filter((arg) => arg.startsWith("--version:"))
|
||||
.map((arg) => arg.replace("--version:", ""))
|
||||
|
||||
const componentVersions = Object.fromEntries(
|
||||
versionArgs.map((entry) => {
|
||||
const [component, version] = entry.split("=")
|
||||
return [component, version]
|
||||
}),
|
||||
)
|
||||
|
||||
const result = await syncReleaseMetadata({
|
||||
componentVersions,
|
||||
write,
|
||||
})
|
||||
|
||||
for (const update of result.updates) {
|
||||
console.log(`${update.changed ? "update" : "keep"} ${update.path}`)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bun
|
||||
import { execFileSync } from "node:child_process"
|
||||
import path from "path"
|
||||
import { validateReleasePleaseConfig } from "../../src/release/config"
|
||||
import { getCompoundEngineeringCounts, syncReleaseMetadata } from "../../src/release/metadata"
|
||||
import { readJson } from "../../src/utils/files"
|
||||
|
||||
type ReleasePleaseManifest = Record<string, string>
|
||||
|
||||
const MANIFEST_RELATIVE_PATH = ".github/.release-please-manifest.json"
|
||||
|
||||
// The release-as staleness check must compare a pin against the version already
|
||||
// released on the base branch (main), NOT the working tree: a release-please PR
|
||||
// bumps the working-tree manifest to the proposed version, which would make a
|
||||
// legitimate pin look stale and block the very release it exists to create.
|
||||
// Returns {} when origin/main is unreachable (e.g. a shallow checkout that did
|
||||
// not fetch it) so the staleness check no-ops rather than risk a false block.
|
||||
function readReleasedManifest(): ReleasePleaseManifest {
|
||||
try {
|
||||
const raw = execFileSync("git", ["show", `origin/main:${MANIFEST_RELATIVE_PATH}`], {
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "ignore"],
|
||||
})
|
||||
return JSON.parse(raw) as ReleasePleaseManifest
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
const releasePleaseConfig = await readJson<{ packages: Record<string, unknown> }>(
|
||||
path.join(process.cwd(), ".github", "release-please-config.json"),
|
||||
)
|
||||
const manifest = await readJson<ReleasePleaseManifest>(
|
||||
path.join(process.cwd(), ...MANIFEST_RELATIVE_PATH.split("/")),
|
||||
)
|
||||
const configErrors = validateReleasePleaseConfig(releasePleaseConfig, readReleasedManifest())
|
||||
const counts = await getCompoundEngineeringCounts(process.cwd())
|
||||
const result = await syncReleaseMetadata({
|
||||
write: false,
|
||||
componentVersions: {
|
||||
marketplace: manifest[".claude-plugin"],
|
||||
"cursor-marketplace": manifest[".cursor-plugin"],
|
||||
},
|
||||
})
|
||||
const changed = result.updates.filter((update) => update.changed)
|
||||
const metadataErrors = result.errors
|
||||
|
||||
if (configErrors.length === 0 && changed.length === 0 && metadataErrors.length === 0) {
|
||||
console.log(
|
||||
`Release metadata is in sync. compound-engineering currently has ${counts.agents} agents, ${counts.skills} skills, and ${counts.mcpServers} MCP server${counts.mcpServers === 1 ? "" : "s"}.`,
|
||||
)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (configErrors.length > 0) {
|
||||
console.error("Release configuration errors detected:")
|
||||
for (const error of configErrors) {
|
||||
console.error(`- ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (metadataErrors.length > 0) {
|
||||
console.error("Release metadata structural errors detected:")
|
||||
for (const error of metadataErrors) {
|
||||
console.error(`- ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (changed.length > 0) {
|
||||
console.error("Release metadata drift detected:")
|
||||
for (const update of changed) {
|
||||
console.error(`- ${update.path}`)
|
||||
}
|
||||
console.error(
|
||||
`Current compound-engineering counts: ${counts.agents} agents, ${counts.skills} skills, ${counts.mcpServers} MCP server${counts.mcpServers === 1 ? "" : "s"}.`,
|
||||
)
|
||||
}
|
||||
process.exit(1)
|
||||
Reference in New Issue
Block a user