| file_type | readme | ||||
|---|---|---|---|---|---|
| title | Release Agent | ||||
| description | Portable agent for multi-repository version management and release automation | ||||
| version | 1.0.0 | ||||
| last_updated | 2026-08-20 | ||||
| owners |
|
||||
| tags |
|
Portable, production-grade agent for managing releases across multiple repository types (control plane, WordPress plugins, WordPress themes).
The Release Agent automates the release preparation workflow (Phase 1):
- Detect repository type (control-plane, plugin, or theme)
- Validate version consistency across all version files
- Bump versions (major/minor/patch) across all files
- Commit version changes with proper messaging
- Create PR to develop branch with version bumps
Phase 2 (planned): Create PR to main, tag, and GitHub release
Supports:
- Control-plane repositories (
.githubwith VERSION + package.json) - WordPress plugins (plugin header + readme.txt + VERSION)
- WordPress themes (style.css header + VERSION)
agents/release/
├── release.agent.js # Main orchestrator (ESM)
├── package.json
├── README.md
└── includes/
├── repoDetector.cjs # Repo type detection
├── versionManager.cjs # Version file handling
├── gitOps.cjs # Git operations
├── githubOps.cjs # GitHub API
└── tests/
├── repoDetector.test.cjs
├── versionManager.test.cjs
└── integration.test.cjs
const { releaseWorkflow } = require('./release.agent.js');
const result = await releaseWorkflow({
scope: 'patch', // 'patch', 'minor', or 'major'
message: 'Bug fixes and improvements',
repoRoot: process.cwd(),
});
console.log(result);
// {
// currentVersion: '1.2.3',
// newVersion: '1.2.4',
// prDevelop: { number: 42, url: '...' },
// status: 'success',
// message: 'Release v1.2.4 ready...'
// }const result = await releaseWorkflow({
scope: 'minor',
dryRun: true, // No commits or PRs created
});const { validateRelease } = require('./release.agent.js');
const validation = await validateRelease({
repoRoot: process.cwd(),
});
if (!validation.isValid) {
console.error('Release validation failed:', validation.errors);
}Required files:
VERSION— Plain text version filepackage.json— npm package manifest
Example:
repository/
├── .github/ # Marker for control-plane
├── VERSION # "1.0.0"
├── package.json # { "version": "1.0.0" }
└── ...
Required files:
VERSION— Plain text version file{plugin}.php— PHP file with plugin header
Optional files:
readme.txt— Plugin readme with "Stable tag: X.Y.Z"package.json— npm package manifest
Example:
my-plugin/
├── VERSION # "2.0.0"
├── my-plugin.php
│ ├── Plugin Name: My Plugin
│ └── Version: 2.0.0
├── readme.txt # Stable tag: 2.0.0
└── package.json
Required files:
VERSION— Plain text version filestyle.css— CSS file with theme header
Optional files:
package.json— npm package manifest
Example:
my-theme/
├── VERSION # "3.0.0"
├── style.css
│ ├── Theme Name: My Theme
│ └── Version: 3.0.0
└── package.json
Plain text file containing semantic version:
1.2.3
Standard npm manifest:
{
"version": "1.2.3"
}PHP file with plugin header:
<?php
/**
* Plugin Name: My Plugin
* Version: 1.2.3
* Description: My plugin description
*/CSS file with theme header:
/*
* Theme Name: My Theme
* Version: 1.2.3
* Description: My theme description
*/WordPress plugin readme file:
=== My Plugin ===
Contributors: author
Stable tag: 1.2.3
Versions follow SemVer (X.Y.Z):
- Patch (1.2.3 → 1.2.4) — Bug fixes, minor changes
- Minor (1.2.3 → 1.3.0) — New features, backward compatible
- Major (1.2.3 → 2.0.0) — Breaking changes, major rewrites
- All version files must exist and be readable
- All version files must contain the same version
- New version must be valid SemVer (X.Y.Z)
- All version files must be writable before bumping
Main release orchestrator.
Parameters:
{
scope: 'patch' | 'minor' | 'major', // Default: 'patch'
dryRun: boolean, // Default: false
message: string, // Release message (optional)
repoRoot: string, // Default: process.cwd()
}Returns:
{
currentVersion: string, // e.g. "1.2.3"
newVersion: string, // e.g. "1.2.4"
prDevelop: {
number: number,
url: string,
},
prMain: { // After develop merges
number: number,
url: string,
},
tag: string, // e.g. "v1.2.4"
release: {
id: string,
url: string,
},
status: 'success' | 'partial' | 'failed',
message: string,
steps: [
{ step: string, status: 'complete' | 'in-progress' | 'failed' },
...
],
}Validate that a release can proceed.
Parameters:
{
repoRoot: string, // Default: process.cwd()
}Returns:
{
isValid: boolean,
errors: string[], // Issues preventing release
warnings: string[], // Non-blocking warnings
repo: {
type: string, // 'control-plane' | 'plugin' | 'theme'
root: string,
versionFiles: string[],
mainFile: string | null,
},
versions: {
VERSION: { path: string, current: string },
packageJson: { path: string, current: string },
plugin: { path: string, current: string }, // plugins only
theme: { path: string, current: string }, // themes only
readme: { path: string, current: string }, // if present
},
}Detects repository type and structure.
Key functions:
detectRepoType(repoRoot)— Detect repo typeisValidRepoStructure(repoConfig)— Validate structuregetVersionFiles(repoConfig)— List version filesgetMainFile(repoConfig)— Get plugin/theme file
Manages version files: detecting, validating, and bumping.
Key functions:
detectAllVersionFiles(repoConfig)— Find all version filesvalidateVersionConsistency(versionMap)— Check versions matchbumpVersion(current, scope)— Calculate new versionapplyVersionBump(versionMap, newVersion)— Update all filesgetCurrentVersion(versionMap)— Get current version
Git operations: branches, commits, tags, pushes.
Key functions:
createBranch(branchName)— Create branchcommitChanges(message, options)— Commit changescreateTag(tagName, message)— Create tagpush(branch, remote)— Push to remotegetLatestTag()— Get latest tag
GitHub API operations: PRs, releases.
Key functions:
createPullRequest(options)— Create PRmergePullRequest(prNumber)— Merge PRcreateGitHubRelease(options)— Create releasegetGitHubUser()— Get authenticated user
npm testnpm run test:unitnpm run test:integrationTest coverage:
- 18 tests for repo type detection
- 24 tests for version management
- Integration tests for multi-repo scenarios
All tests passing: ✓ 42/42
- Node.js 18+
- Git 2.30+
- GitHub CLI (
gh) for GitHub operations
# GitHub authentication (required for PR/release creation)
gh auth login
# Verify authentication
gh auth statusconst result = await releaseWorkflow({
scope: 'patch',
message: 'Fix: Critical security update',
repoRoot: '/path/to/plugin',
});
console.log(`Released v${result.newVersion}`);
console.log(`PR: ${result.prDevelop.url}`);const result = await releaseWorkflow({
scope: 'minor',
message: 'Add: New admin features',
repoRoot: '/path/to/theme',
});
if (result.status === 'success') {
console.log(`v${result.currentVersion} → v${result.newVersion}`);
}const validation = await validateRelease();
if (validation.isValid) {
const release = await releaseWorkflow({
scope: 'patch',
});
} else {
console.error('Validation failed:', validation.errors);
}All functions return null or false on failure. Check the agent result status field:
const result = await releaseWorkflow({ scope: 'patch' });
if (result.status === 'failed') {
console.error(result.message);
console.error(result.steps); // See which step failed
}Ensure your repo has the required version files:
- Control-plane:
VERSION+.github/directory - Plugin:
VERSION+{plugin}.phpwith plugin header - Theme:
VERSION+style.csswith theme header
All version files must contain the same version. Run validateRelease() to see which files are inconsistent.
Commit or stash uncommitted changes before running releaseWorkflow().
Run gh auth login to authenticate with GitHub CLI.
- PHASE_5_IMPLEMENTATION_PLAN.md — Phase 5 specification
- agents/changelog/README.md — Changelog agent (Phase 5)
Maintained by the 🤖 LightSpeedWP Automation Team
Please see CONTRIBUTING.md for details.