feat: implement optimization #9 - release notes from CHANGELOG
Add release notes extraction from CHANGELOG for publishing: - Create ChangelogParser class to extract version sections from CHANGELOG - Support multiple output formats: markdown, plain text, HTML - Add 'release notes VERSION' CLI command to extract notes - Auto-detect latest version if not specified - Support piping to gh/gitea release commands - Save to file with --output option - Plain text format removes markdown formatting - HTML format converts markdown to HTML This streamlines creating release notes for GitHub/Gitea releases by extracting CHANGELOG content automatically. Usage: release notes 0.10.0 # Extract markdown notes release notes # Latest version release notes 0.10.0 --format plain # Plain text release notes 0.10.0 -o notes.md # Save to file release notes 0.10.0 | gh release create v0.10.0 -F - 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ from typing import Optional
|
||||
from ..core.manager import ReleaseManager
|
||||
from ..utils.version import VersionManager
|
||||
from ..changelog.editor import ChangelogEditor
|
||||
from ..changelog.parser import ChangelogParser
|
||||
from ..summary.generator import SummaryGenerator
|
||||
|
||||
|
||||
@@ -358,5 +359,58 @@ def summary(ctx, version: str, output: Optional[Path]):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@main.command('notes')
|
||||
@click.argument('version', required=False)
|
||||
@click.option('--format', 'output_format', type=click.Choice(['markdown', 'plain', 'html']),
|
||||
default='markdown', help='Output format (default: markdown)')
|
||||
@click.option('--output', '-o', default=None, type=click.Path(path_type=Path),
|
||||
help='Save to file instead of stdout')
|
||||
@click.pass_context
|
||||
def notes(ctx, version: Optional[str], output_format: str, output: Optional[Path]):
|
||||
"""Extract release notes from CHANGELOG.md.
|
||||
|
||||
Extracts the CHANGELOG section for a specific version and outputs it
|
||||
in various formats. Useful for creating GitHub/Gitea release notes.
|
||||
|
||||
If no version is specified, uses the latest version from CHANGELOG.
|
||||
|
||||
Examples:
|
||||
release notes 0.10.0 # Extract v0.10.0 notes (markdown)
|
||||
release notes # Extract latest version notes
|
||||
release notes 0.10.0 --format plain # Plain text format
|
||||
release notes 0.10.0 -o notes.md # Save to file
|
||||
release notes 0.10.0 | gh release create v0.10.0 -F - # Pipe to gh
|
||||
"""
|
||||
project_root = ctx.obj['project_root'] or Path.cwd()
|
||||
changelog_path = project_root / 'CHANGELOG.md'
|
||||
|
||||
parser = ChangelogParser(changelog_path)
|
||||
|
||||
# Get version (use latest if not specified)
|
||||
if version is None:
|
||||
version = parser.get_latest_version()
|
||||
if version is None:
|
||||
print("❌ Could not determine version from CHANGELOG.md")
|
||||
sys.exit(1)
|
||||
print(f"Using latest version: {version}", file=sys.stderr)
|
||||
|
||||
# Extract content
|
||||
content = parser.extract_version_section(version, format=output_format)
|
||||
|
||||
# Check for errors
|
||||
if content.startswith("Error:") or content.startswith("Warning:"):
|
||||
print(content)
|
||||
sys.exit(1 if content.startswith("Error:") else 0)
|
||||
|
||||
# Output
|
||||
if output:
|
||||
if not output.is_absolute():
|
||||
output = project_root / output
|
||||
output.write_text(content)
|
||||
print(f"✅ Release notes written to {output}", file=sys.stderr)
|
||||
else:
|
||||
print(content)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user