Review

/laravel-agent:git:release

Create release with automatic changelog generation

Overview

The /git:release command creates a new release with automatic changelog generation from conventional commits. It handles version bumping, changelog creation, file updates, git tagging, and GitHub release creation following semantic versioning and the Keep a Changelog format.

Usage

/laravel-agent:git:release <version|major|minor|patch> [--dry-run] [--no-tag]

Examples

# Bump patch version (1.0.0 → 1.0.1)
/laravel-agent:git:release patch

# Bump minor version (1.0.0 → 1.1.0)
/laravel-agent:git:release minor

# Bump major version (1.0.0 → 2.0.0)
/laravel-agent:git:release major

# Set specific version
/laravel-agent:git:release 2.0.0

# Preview without creating
/laravel-agent:git:release minor --dry-run

# Create release without git tag
/laravel-agent:git:release patch --no-tag

# Pre-release versions
/laravel-agent:git:release 1.1.0-beta.1
/laravel-agent:git:release 1.1.0-rc.1
/laravel-agent:git:release 1.1.0-alpha.1

Version Bump Options

Option Example Description
patch 1.0.0 → 1.0.1 Bug fixes and patches
minor 1.0.0 → 1.1.0 New features (backwards-compatible)
major 1.0.0 → 2.0.0 Breaking changes
x.y.z 1.0.0 → 2.5.3 Specific version number

Release Process

The command follows these steps to create a complete release:

1. Determine Current Version

The command identifies the current version from git tags or composer.json:

# From git tags
current=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0")

# Or from composer.json
current=$(jq -r '.version // "0.0.0"' composer.json)

2. Calculate New Version

Based on the bump type, the new version is calculated:

# Parse current version
IFS='.' read -r major minor patch <<< "${current#v}"

case "$bump" in
    major) new="$((major + 1)).0.0" ;;
    minor) new="$major.$((minor + 1)).0" ;;
    patch) new="$major.$minor.$((patch + 1))" ;;
    *) new="$bump" ;; # Specific version
esac

3. Gather Commits Since Last Release

All commits since the last release are collected:

# Get commits since last tag
if [ -n "$current" ]; then
    commits=$(git log $current..HEAD --pretty=format:"%s|%h|%an" --no-merges)
else
    commits=$(git log --pretty=format:"%s|%h|%an" --no-merges)
fi

4. Generate Changelog

Conventional commits are parsed and categorized into a structured changelog:

# Changelog

## [1.1.0] - 2024-01-15

### Features
- **invoice:** Add PDF export functionality (#123) - @developer
- **auth:** Add two-factor authentication (#124) - @developer

### Bug Fixes
- **dashboard:** Fix chart rendering on mobile (#125) - @developer
- **api:** Handle null response from payment gateway (#126) - @developer

### Performance
- **queries:** Add database indexes for user lookups (#127) - @developer

### Breaking Changes
- **api:** Response format changed to JSON:API (#128)
  - Migration guide: docs/api-v2.md

### Other Changes
- **deps:** Update Laravel to 11.x
- **ci:** Add GitHub Actions workflow
- **docs:** Update API documentation

### Contributors
- @developer1 (5 commits)
- @developer2 (3 commits)

5. Update Version Files

Version numbers are updated in relevant project files:

# Update composer.json
jq ".version = \"$new\"" composer.json > tmp.json && mv tmp.json composer.json

# Update package.json (if exists)
if [ -f package.json ]; then
    jq ".version = \"$new\"" package.json > tmp.json && mv tmp.json package.json
fi

# Update config/app.php version constant (if used)
sed -i "s/'version' => '.*'/'version' => '$new'/" config/app.php 2>/dev/null || true

6. Create Release Commit

A release commit is created with the changelog summary:

git add -A
git commit -m "chore(release): $new

$(cat CHANGELOG.md | head -50)
"

7. Create Git Tag

An annotated tag is created with release highlights:

# Create annotated tag
git tag -a "v$new" -m "Release v$new

## Highlights
<Top 3 changes>

## Full Changelog
See CHANGELOG.md
"

8. Push Release

The release is pushed to the remote repository and GitHub:

# Push commits and tags
git push origin main --follow-tags

# Create GitHub release
gh release create "v$new" \
    --title "v$new" \
    --notes-file CHANGELOG.md

Example Output

After running the command, you'll see a summary like this:

## Release Created

**Version:** v1.1.0
**Date:** 2024-01-15

### Summary
- Features: 2
- Bug Fixes: 2
- Breaking Changes: 1

### Highlights
1. PDF export for invoices
2. Two-factor authentication
3. Performance improvements

### Files Updated
- CHANGELOG.md
- composer.json
- package.json

### Commands Run
```bash
git add -A
git commit -m "chore(release): 1.1.0"
git tag -a v1.1.0
git push origin main --follow-tags
gh release create v1.1.0
```

### Next Steps
1. Verify release on GitHub
2. Deploy to production
3. Announce release

Changelog Format (Keep a Changelog)

The generated changelog follows the Keep a Changelog format:

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security

## [1.1.0] - 2024-01-15

### Added
- PDF export for invoices (#123)
- Two-factor authentication (#124)

### Fixed
- Dashboard chart rendering on mobile (#125)

### Security
- Update dependencies to patch CVE-2024-XXXX

## [1.0.0] - 2024-01-01

### Added
- Initial release

Semantic Versioning Rules

The command follows Semantic Versioning 2.0.0 guidelines:

Change Type Version Bump When
Breaking change Major API incompatible changes
New feature Minor Backwards-compatible additions
Bug fix Patch Backwards-compatible fixes
Deprecation Minor Feature deprecated (still works)
Security fix Patch Security vulnerability fixed

Conventional Commits

The changelog generation parses conventional commit messages. Use these prefixes in your commits:

  • feat: - New features (appears in "Features" section)
  • fix: - Bug fixes (appears in "Bug Fixes" section)
  • perf: - Performance improvements (appears in "Performance" section)
  • docs: - Documentation changes (appears in "Other Changes")
  • style: - Code style changes (appears in "Other Changes")
  • refactor: - Code refactoring (appears in "Other Changes")
  • test: - Test additions or updates (appears in "Other Changes")
  • chore: - Maintenance tasks (appears in "Other Changes")
  • BREAKING CHANGE: - Breaking changes (appears in "Breaking Changes")

Command Options

Option Description
--dry-run Preview the release without creating it. Shows what would be changed.
--no-tag Create release commit without creating a git tag.

Files Updated

The command updates or creates these files:

  • CHANGELOG.md - Changelog with release history
  • composer.json - Version field updated
  • package.json - Version field updated (if exists)
  • config/app.php - Version constant updated (if exists)

Best Practices

  1. Use conventional commits - Always follow the conventional commit format for accurate changelog generation
  2. Review with --dry-run - Preview changes before creating the release
  3. Keep unreleased changes - Maintain an [Unreleased] section in CHANGELOG.md for work in progress
  4. Document breaking changes - Include migration guides for major version bumps
  5. Test before release - Ensure all tests pass before creating a release
  6. Follow semver strictly - Be consistent with semantic versioning rules
  7. Verify GitHub release - Check that the GitHub release was created successfully

Pre-release Versions

For alpha, beta, and release candidate versions, use the following format:

# Beta releases
/laravel-agent:git:release 1.1.0-beta.1
/laravel-agent:git:release 1.1.0-beta.2

# Release candidates
/laravel-agent:git:release 1.1.0-rc.1
/laravel-agent:git:release 1.1.0-rc.2

# Alpha releases
/laravel-agent:git:release 1.1.0-alpha.1

See Also