Adds a new `/core:release` command to streamline the release process for modules. This command automates the following workflow: - Bumps the version in `package.json` (and `gemini-extension.json` if it exists). - Generates a `CHANGELOG.md` entry from conventional commit messages. - Commits the changes with a `chore(release): vX.Y.Z` message. - Creates and pushes a new git tag to trigger the CI release. A `--preview` flag is included to allow for a dry run of the release process without making any changes.
172 lines
4.7 KiB
Bash
Executable file
172 lines
4.7 KiB
Bash
Executable file
#!/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."
|