@cloudkinetix/bmad-enhanced
Version:
Cloud-Kinetix enhanced fork of BMAD-METHOD - Breakthrough Method of Agile AI-driven Development with robust versioning and unified validation.
174 lines (138 loc) • 5.72 kB
JavaScript
/**
* Semantic-release plugin to sync Cloud-Kinetix package version
* and update upstream tracking metadata
* Automatically detects GitHub CLI token if available
*/
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
function setupGitHubToken(logger) {
// Check if GITHUB_TOKEN or GH_TOKEN is already set
if (process.env.GITHUB_TOKEN || process.env.GH_TOKEN) {
logger.log("✅ GitHub token already available");
return;
}
try {
// Try to get token from GitHub CLI
logger.log("🔍 Checking for GitHub CLI authentication...");
const ghToken = execSync("gh auth token", { encoding: "utf8" }).trim();
if (ghToken && ghToken.startsWith("gho_")) {
process.env.GITHUB_TOKEN = ghToken;
logger.log("✅ Using GitHub CLI token for authentication");
} else {
logger.log("⚠️ GitHub CLI token not found or invalid");
}
} catch (error) {
logger.log("⚠️ GitHub CLI not available or not authenticated");
logger.log(" Run: gh auth login");
}
}
function verifyConditions(pluginConfig, context) {
const { logger } = context;
// Setup GitHub token automatically before any verification
setupGitHubToken(logger);
}
function prepare(pluginConfig, context) {
const { nextRelease, logger } = context;
// Path to main package.json (single package structure now)
const packagePath = path.join(process.cwd(), "package.json");
if (!fs.existsSync(packagePath)) {
logger.log("package.json not found");
return;
}
// Read package.json
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
// Update version and metadata
packageJson.version = nextRelease.version;
// Add or update metadata for upstream tracking
if (!packageJson.metadata) {
packageJson.metadata = {};
}
// Keep existing upstream tracking info
packageJson.metadata.lastSync = new Date().toISOString().split("T")[0];
// Write back
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + "\n");
logger.log(`Updated package.json to version ${nextRelease.version}`);
// Update UPSTREAM.md with new version mapping
const upstreamPath = path.join(process.cwd(), "UPSTREAM.md");
if (fs.existsSync(upstreamPath)) {
let upstreamContent = fs.readFileSync(upstreamPath, "utf8");
// Update current version
upstreamContent = upstreamContent.replace(
/- \*\*Current CK Installer Version\*\*: .+/,
`- **Current CK Installer Version**: ${nextRelease.version}`
);
// Update last sync date
upstreamContent = upstreamContent.replace(
/- \*\*Last Sync Date\*\*: .+/,
`- **Last Sync Date**: ${new Date().toISOString().split("T")[0]}`
);
fs.writeFileSync(upstreamPath, upstreamContent);
logger.log("Updated UPSTREAM.md tracking file");
}
// Update README-CK.md version references
const readmePath = path.join(process.cwd(), "README-CK.md");
if (fs.existsSync(readmePath)) {
let readmeContent = fs.readFileSync(readmePath, "utf8");
// Update current version in version history section
readmeContent = readmeContent.replace(
/- \*\*Current\*\*: .+ -/,
`- **Current**: ${nextRelease.version} -`
);
fs.writeFileSync(readmePath, readmeContent);
logger.log("Updated README-CK.md version references");
}
// Update installer README
const installerReadmePath = path.join(process.cwd(), "README-installer.md");
if (fs.existsSync(installerReadmePath)) {
let installerReadmeContent = fs.readFileSync(installerReadmePath, "utf8");
// Update current version
installerReadmeContent = installerReadmeContent.replace(
/- \*\*Current Version\*\*: .+/,
`- **Current Version**: ${nextRelease.version}`
);
// Update release date
installerReadmeContent = installerReadmeContent.replace(
/- \*\*Release Date\*\*: .+/,
`- **Release Date**: ${new Date().toISOString().split("T")[0]}`
);
fs.writeFileSync(installerReadmePath, installerReadmeContent);
logger.log("Updated installer README version");
}
// Update VERSIONING.md current version
const versioningPath = path.join(process.cwd(), "docs", "VERSIONING.md");
if (fs.existsSync(versioningPath)) {
let versioningContent = fs.readFileSync(versioningPath, "utf8");
// Update current version in installer package section
versioningContent = versioningContent.replace(
/- Current: .+/,
`- Current: ${nextRelease.version}`
);
fs.writeFileSync(versioningPath, versioningContent);
logger.log("Updated VERSIONING.md current version");
}
// Update main README.md version references
const mainReadmePath = path.join(process.cwd(), "README.md");
if (fs.existsSync(mainReadmePath)) {
let readmeContent = fs.readFileSync(mainReadmePath, "utf8");
const majorMinor = nextRelease.version.split('.').slice(0, 2).join('.');
// Update "Latest CK Version: X.X.X" (including beta versions)
readmeContent = readmeContent.replace(
/### 🆕 Latest CK Version: .+$/gm,
`### 🆕 Latest CK Version: ${nextRelease.version}`
);
// Update "LATEST: vX.X.X" (including beta versions)
readmeContent = readmeContent.replace(
/#### 🎉 \*\*LATEST: v.+? -/g,
`#### 🎉 **LATEST: v${nextRelease.version} -`
);
// Update "New vX.X" in feature announcements (use major.minor format)
readmeContent = readmeContent.replace(
/> 🎉 \*\*New v\d+\.\d+\*\*/g,
`> 🎉 **New v${majorMinor}**`
);
fs.writeFileSync(mainReadmePath, readmeContent);
logger.log("Updated README.md version references");
}
}
module.exports = { verifyConditions, prepare };