`homeboy release`
Synopsis
homeboy release [OPTIONS] [COMPONENTS]...By default Homeboy auto-detects the bump from commit history. Use --bump <major|minor|patch|VERSION> to force a bump type or explicit version.
Legacy positional bump syntax is still accepted for compatibility: homeboy release <COMPONENT> <BUMP_TYPE>.
Options
--dry-run: Preview the release plan without executing--project <PROJECT>/-p <PROJECT>: Release components from a project--outdated: With--project, release only components with unreleased commits--path <PATH>: Override local path for a single-component release--deploy: Deploy this component to all projects that use it after release--recover: Recover from an interrupted release--skip-checks: Skip pre-release lint/test checks--bump <BUMP>: Forcemajor,minor,patch, or an explicit version like2.0.0--force-lower-bump: Allow a forced bump lower than the commit-derived recommendation--skip-publish: Skip publish/package steps; useful when CI publishes after the tag is pushed--no-github-release: Skip GitHub Release creation while still tagging and pushing--git-identity <IDENTITY>: Configure git identity for release commits/tags; usebotorName <email>
Description
homeboy release executes component releases: detects or applies a version bump, finalizes generated changelog entries, commits, tags, pushes, and optionally publishes release artifacts. Use --dry-run to preview the release plan without making changes.
When --bump requests a lower keyword bump than Homeboy detects from releasable commits, release execution requires confirmation in an interactive terminal. Non-interactive runs must pass --force-lower-bump; otherwise Homeboy refuses before creating release artifacts, commits, tags, or pushes. Dry-run still returns the plan and semver recommendation for review.
Recommended Workflow
# 1. Review changes since last release
homeboy changes <component_id>
# 2. Preview the release (validates configuration, shows plan)
homeboy release <component_id> --dry-run
# 3. Execute the release
homeboy release <component_id>Release Pipeline
The release command coordinates versioning, committing, tagging, and pushing.
Pipeline steps
Release pipelines support two step types:
- Core steps:
build,changes,version,git.commit,git.tag,git.push - Extension-backed steps: any custom step type implemented as a extension action named
release.<step_type>
Core step: git.commit
Commits release changes (version bumps, changelog updates) before tagging.
Auto-insert behavior: If your pipeline has a git.tag step but no git.commit step, a git.commit step is automatically inserted before git.tag. This ensures version changes are committed before tagging.
Default commit message: release: v{version}
Custom message:
{
"id": "git.commit",
"type": "git.commit",
"config": {
"message": "chore: release v1.2.3"
}
}Working tree requirements
Release requires a clean working tree, with two exceptions:
- Changelog: May have uncommitted entries (these will be finalized during release)
- Version targets: May be staged (though unusual)
These files are modified during the release anyway and included in the release commit.
Any other uncommitted changes will cause the release to fail with guidance to commit first.
Pipeline step: extension.run
Use extension.run to execute a extension runtime command as part of the release pipeline.
Example step configuration:
{
"id": "scrape",
"type": "extension.run",
"needs": ["build"],
"config": {
"extension": "bandcamp-scraper",
"inputs": [
{ "id": "artist", "value": "some-artist" }
],
"args": ["--verbose"]
}
}config.extensionis required.config.inputsis optional; each entry must includeidandvalue.config.argsis optional; each entry is a CLI arg string.- Output includes
stdout,stderr,exitCode,success, and the release payload.
Release payload
All extension-backed release steps receive a shared payload:
{
"release": {
"version": "1.2.3",
"tag": "v1.2.3",
"notes": "- Added feature",
"component_id": "homeboy",
"local_path": "/path/to/repo",
"artifacts": [
{ "path": "dist/homeboy-macos.zip", "type": "binary", "platform": "macos" }
]
}
}When a step provides additional config, it is included as payload.config alongside payload.release.
JSON output
Note: all command output is wrapped in the global JSON envelope described in the JSON output contract. The object below is the
datapayload.
Note: all command output is wrapped in the global JSON envelope described in the JSON output contract. The object below is the data payload.
{
"command": "release",
"result": {
"component_id": "<component_id>",
"bump_type": "patch",
"dry_run": true,
"no_tag": false,
"no_push": false,
"plan": {
"component_id": "<component_id>",
"enabled": true,
"steps": [...],
"warnings": [],
"hints": []
}
}
}CI / bot semver recommendation example
Note: all command output is wrapped in the global JSON envelope described in the JSON output contract. The object below is the data payload.
homeboy release <component_id> --dry-run --jsonWith --dry-run:
data.result.plan.semver_recommendation
For automation, run dry-run JSON and consume:
{
"latest_tag": "v0.56.1",
"range": "v0.56.1..HEAD",
"commits": [
{
"sha": "abc1234",
"subject": "feat(test): changed-since impact-scoped test execution",
"commit_type": "feature",
"breaking": false
}
],
"recommended_bump": "minor",
"requested_bump": "patch",
"is_underbump": true,
"reasons": [
"abc1234 feat(test): changed-since impact-scoped test execution"
]
}Semver recommendation is exposed at:
Example payload:
{
"command": "release",
"result": {
"component_id": "<component_id>",
"bump_type": "patch",
"dry_run": false,
"no_tag": false,
"no_push": false,
"run": {
"status": "success",
"warnings": [],
"summary": {
"total_steps": 5,
"succeeded": 5,
"failed": 0,
"skipped": 0,
"missing": 0,
"next_actions": []
},
"steps": [...]
}
}
}Pipeline status values
success– All steps completed successfullypartial_success– Some steps succeeded, others failed (idempotent retry is safe)failed– All executed steps failedskipped– Pipeline disabled or all steps skipped due to failed dependenciesmissing– Required extension actions not found
Idempotent retry
Use this in CI to inspect Homeboy’s commit-derived recommendation before tagging/publish. Pass --bump when automation or a maintainer needs to override the detected bump. If automation intentionally publishes a lower keyword bump than recommended_bump, pass --force-lower-bump with the release command.
- GitHub releases: If tag exists, assets are updated via
--clobber - crates.io: If version already published, step skips gracefully
Without --dry-run:
Publish steps are designed to be idempotent: