diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 359d0be..a684368 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -49,6 +49,9 @@ "version": "0.1.0" }, { + "name": "core", + "source": "./claude/core", + "description": "Core functionality - release management", "name": "issue", "source": "./claude/issue", "description": "Integration with GitHub Issues", diff --git a/claude/core/.claude-plugin/plugin.json b/claude/core/.claude-plugin/plugin.json new file mode 100644 index 0000000..e29c4be --- /dev/null +++ b/claude/core/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "core", + "description": "Core functionality - release management", + "version": "0.1.0", + "author": { + "name": "Host UK" + } +} diff --git a/claude/core/commands/release.md b/claude/core/commands/release.md new file mode 100644 index 0000000..6265599 --- /dev/null +++ b/claude/core/commands/release.md @@ -0,0 +1,44 @@ +--- +name: release +description: Release a new version of a module +args: [patch|minor|major] +flags: + preview: + description: Show what would happen without actually making a release + type: boolean + default: false +--- + +# Release new version + +Streamlines the release process for modules. + +## Commands + +### Bump patch version +`/core:release patch` + +### Bump minor version +`/core:release minor` + +### Bump major version +`/core:release major` + +### Preview release +`/core:release patch --preview` + +## Workflow + +1. **Bump version**: Bumps the version in `package.json` and other necessary files. +2. **Update CHANGELOG.md**: Generates a new entry in the changelog based on commit history. +3. **Create git tag**: Creates a new git tag for the release. +4. **Push tag**: Pushes the new tag to the remote repository. +5. **Trigger CI release**: The new tag should trigger the CI/CD release pipeline. + +## Implementation + +This command is implemented by the `release.sh` script. + +```bash +/bin/bash ../scripts/release.sh "$@" +``` diff --git a/claude/core/scripts/release.sh b/claude/core/scripts/release.sh new file mode 100755 index 0000000..45b87eb --- /dev/null +++ b/claude/core/scripts/release.sh @@ -0,0 +1,172 @@ +#!/bin/bash + +# Exit on error +set -e + +# --- Argument Parsing --- +BUMP_TYPE="" +PREVIEW=false + +# Loop through all arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + patch|minor|major) + if [ -n "$BUMP_TYPE" ]; then + echo "Error: Only one version bump type (patch, minor, major) can be specified." >&2 + exit 1 + fi + BUMP_TYPE="$1" + ;; + --preview) + PREVIEW=true + ;; + *) + # Stop parsing at the first non-recognized argument, assuming it's for another script + break + ;; + esac + shift +done + +# --- Validation --- +if [ -z "$BUMP_TYPE" ]; then + echo "Usage: /core:release [patch|minor|major] [--preview]" + echo "Error: A version bump type must be specified." >&2 + exit 1 +fi + +echo "Configuration:" +echo " Bump Type: $BUMP_TYPE" +echo " Preview Mode: $PREVIEW" +echo "-------------------------" + +# --- Version Calculation --- +PACKAGE_JSON_PATH="package.json" + +if [ ! -f "$PACKAGE_JSON_PATH" ]; then + echo "Error: package.json not found in the current directory." >&2 + exit 1 +fi + +CURRENT_VERSION=$(jq -r '.version' "$PACKAGE_JSON_PATH") +echo "Current version: $CURRENT_VERSION" + +# Version bumping logic +IFS='.' read -r -a VERSION_PARTS <<< "$CURRENT_VERSION" +MAJOR=${VERSION_PARTS[0]} +MINOR=${VERSION_PARTS[1]} +PATCH=${VERSION_PARTS[2]} + +case $BUMP_TYPE in + patch) + PATCH=$((PATCH + 1)) + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; +esac + +NEW_VERSION="$MAJOR.$MINOR.$PATCH" +echo "New version: $NEW_VERSION" + +# --- Changelog Generation --- +# Get the latest tag, or the first commit if no tags exist +LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD) + +# Get commit messages since the last tag +COMMIT_LOG=$(git log "$LATEST_TAG"..HEAD --pretty=format:"%s") + +# Prepare changelog entry +CHANGELOG_ENTRY="## [$NEW_VERSION] - $(date +%Y-%m-%d)\n\n" +ADDED="" +FIXED="" +OTHER="" + +while IFS= read -r line; do + if [[ "$line" == feat* ]]; then + ADDED="$ADDED- ${line#*: }\n" + elif [[ "$line" == fix* ]]; then + FIXED="$FIXED- ${line#*: }\n" + else + OTHER="$OTHER- $line\n" + fi +done <<< "$COMMIT_LOG" + +if [ -n "$ADDED" ]; then + CHANGELOG_ENTRY="${CHANGELOG_ENTRY}### Added\n$ADDED\n" +fi + +if [ -n "$FIXED" ]; then + CHANGELOG_ENTRY="${CHANGELOG_ENTRY}### Fixed\n$FIXED\n" +fi + +if [ -n "$OTHER" ]; then + CHANGELOG_ENTRY="${CHANGELOG_ENTRY}### Other\n$OTHER\n" +fi + +echo -e "\nGenerated CHANGELOG entry:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━\n$CHANGELOG_ENTRY━━━━━━━━━━━━━━━━━━━━━━━━━━━" + +# --- Execution --- +GEMINI_EXTENSION_PATH="gemini-extension.json" +CHANGELOG_PATH="CHANGELOG.md" + +if [ "$PREVIEW" = true ]; then + echo -e "\nPreview mode enabled. The following actions would be taken:" + echo " - Bump version in $PACKAGE_JSON_PATH to $NEW_VERSION" + echo " - Bump version in $GEMINI_EXTENSION_PATH to $NEW_VERSION (if it exists)" + echo " - Prepend the generated entry to $CHANGELOG_PATH" + echo " - git add (conditionally including $GEMINI_EXTENSION_PATH if it exists)" + echo " - git commit -m \"chore(release): v$NEW_VERSION\"" + echo " - git tag v$NEW_VERSION" + echo " - git push origin HEAD --follow-tags" + exit 0 +fi + +read -p "Proceed with release? [y/N] " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Release cancelled." + exit 1 +fi + +echo "Proceeding with release..." + +# Update package.json +jq --arg v "$NEW_VERSION" '.version = $v' "$PACKAGE_JSON_PATH" > tmp.$$.json && mv tmp.$$.json "$PACKAGE_JSON_PATH" +echo "Updated $PACKAGE_JSON_PATH" + +# Update gemini-extension.json +if [ -f "$GEMINI_EXTENSION_PATH" ]; then + jq --arg v "$NEW_VERSION" '.version = $v' "$GEMINI_EXTENSION_PATH" > tmp.$$.json && mv tmp.$$.json "$GEMINI_EXTENSION_PATH" + echo "Updated $GEMINI_EXTENSION_PATH" +fi + +# Update CHANGELOG.md +if [ ! -f "$CHANGELOG_PATH" ]; then + echo -e "# Changelog\n\nAll notable changes to this project will be documented in this file.\n" > "$CHANGELOG_PATH" +fi +echo -e "$CHANGELOG_ENTRY$(cat $CHANGELOG_PATH)" > "$CHANGELOG_PATH" +echo "Updated $CHANGELOG_PATH" + +# Git operations +echo "Committing changes..." +FILES_TO_ADD=("$PACKAGE_JSON_PATH" "$CHANGELOG_PATH") +if [ -f "$GEMINI_EXTENSION_PATH" ]; then + FILES_TO_ADD+=("$GEMINI_EXTENSION_PATH") +fi +git add "${FILES_TO_ADD[@]}" +git commit -m "chore(release): v$NEW_VERSION" + +echo "Creating git tag..." +git tag "v$NEW_VERSION" + +echo "Pushing changes and tag..." +git push origin HEAD --follow-tags + +echo "Release complete."