feat: Add version bump script for releases
Automates version updates across: - internal/cmd/version.go (CLI version) - npm-package/package.json (npm version) - CHANGELOG.md (release entry) Usage: ./scripts/bump-version.sh X.Y.Z --commit --tag --push --install 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
8f276febd3
commit
48ce8d8146
315
scripts/bump-version.sh
Executable file
315
scripts/bump-version.sh
Executable file
@@ -0,0 +1,315 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# =============================================================================
|
||||
# VERSION BUMP SCRIPT FOR GAS TOWN
|
||||
# =============================================================================
|
||||
#
|
||||
# This script handles version bumping for Gas Town releases.
|
||||
# It updates version numbers across all components.
|
||||
#
|
||||
# QUICK START:
|
||||
# ./scripts/bump-version.sh X.Y.Z --commit --tag --push --install
|
||||
#
|
||||
# WHAT IT UPDATES:
|
||||
# - internal/cmd/version.go - CLI version constant
|
||||
# - npm-package/package.json - npm package version
|
||||
# - CHANGELOG.md - Creates release entry from [Unreleased]
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Usage message
|
||||
usage() {
|
||||
echo "Usage: $0 <version> [--commit] [--tag] [--push] [--install]"
|
||||
echo ""
|
||||
echo "Bump version across all Gas Town components."
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " <version> Semantic version (e.g., 0.2.0, 1.0.0)"
|
||||
echo " --commit Automatically create a git commit"
|
||||
echo " --tag Create annotated git tag (requires --commit)"
|
||||
echo " --push Push commit and tag to origin (requires --tag)"
|
||||
echo " --install Rebuild and install gt binary to GOPATH/bin"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 0.2.0 # Update versions and show diff"
|
||||
echo " $0 0.2.0 --install # Update versions and rebuild/install gt"
|
||||
echo " $0 0.2.0 --commit # Update versions and commit"
|
||||
echo " $0 0.2.0 --commit --tag # Update, commit, and tag"
|
||||
echo " $0 0.2.0 --commit --tag --push # Full release preparation"
|
||||
echo ""
|
||||
echo "Recommended release command:"
|
||||
echo " $0 X.Y.Z --commit --tag --push --install"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Validate semantic versioning
|
||||
validate_version() {
|
||||
local version=$1
|
||||
if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo -e "${RED}Error: Invalid version format '$version'${NC}"
|
||||
echo "Expected semantic version format: MAJOR.MINOR.PATCH (e.g., 0.2.0)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get current version from version.go
|
||||
get_current_version() {
|
||||
grep 'Version = ' internal/cmd/version.go | sed 's/.*"\(.*\)".*/\1/'
|
||||
}
|
||||
|
||||
# Update a file with sed (cross-platform compatible)
|
||||
update_file() {
|
||||
local file=$1
|
||||
local old_pattern=$2
|
||||
local new_text=$3
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' "s|$old_pattern|$new_text|g" "$file"
|
||||
else
|
||||
sed -i "s|$old_pattern|$new_text|g" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
# Update CHANGELOG.md: move [Unreleased] to [version]
|
||||
update_changelog() {
|
||||
local version=$1
|
||||
local date=$(date +%Y-%m-%d)
|
||||
|
||||
if [ ! -f "CHANGELOG.md" ]; then
|
||||
echo -e "${YELLOW}Warning: CHANGELOG.md not found, skipping${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if there's an [Unreleased] section
|
||||
if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then
|
||||
echo -e "${YELLOW}Warning: No [Unreleased] section in CHANGELOG.md${NC}"
|
||||
echo -e "${YELLOW}You may need to manually update CHANGELOG.md${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' "s/## \[Unreleased\]/## [Unreleased]\n\n## [$version] - $date/" CHANGELOG.md
|
||||
else
|
||||
sed -i "s/## \[Unreleased\]/## [Unreleased]\n\n## [$version] - $date/" CHANGELOG.md
|
||||
fi
|
||||
}
|
||||
|
||||
# Main script
|
||||
main() {
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
NEW_VERSION=$1
|
||||
AUTO_COMMIT=false
|
||||
AUTO_TAG=false
|
||||
AUTO_PUSH=false
|
||||
AUTO_INSTALL=false
|
||||
|
||||
# Parse flags
|
||||
shift
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--commit)
|
||||
AUTO_COMMIT=true
|
||||
;;
|
||||
--tag)
|
||||
AUTO_TAG=true
|
||||
;;
|
||||
--push)
|
||||
AUTO_PUSH=true
|
||||
;;
|
||||
--install)
|
||||
AUTO_INSTALL=true
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Error: Unknown option '$1'${NC}"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Validate flag dependencies
|
||||
if [ "$AUTO_TAG" = true ] && [ "$AUTO_COMMIT" = false ]; then
|
||||
echo -e "${RED}Error: --tag requires --commit${NC}"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$AUTO_PUSH" = true ] && [ "$AUTO_TAG" = false ]; then
|
||||
echo -e "${RED}Error: --push requires --tag${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate version format
|
||||
validate_version "$NEW_VERSION"
|
||||
|
||||
# Check if we're in the repo root
|
||||
if [ ! -f "internal/cmd/version.go" ]; then
|
||||
echo -e "${RED}Error: Must run from repository root${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get current version
|
||||
CURRENT_VERSION=$(get_current_version)
|
||||
|
||||
echo -e "${YELLOW}Bumping version: $CURRENT_VERSION → $NEW_VERSION${NC}"
|
||||
echo ""
|
||||
|
||||
# Check for uncommitted changes
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
echo -e "${YELLOW}Warning: You have uncommitted changes${NC}"
|
||||
if [ "$AUTO_COMMIT" = true ]; then
|
||||
echo -e "${RED}Error: Cannot auto-commit with existing uncommitted changes${NC}"
|
||||
exit 1
|
||||
fi
|
||||
read -p "Continue anyway? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Updating version files..."
|
||||
|
||||
# 1. Update internal/cmd/version.go
|
||||
echo " • internal/cmd/version.go"
|
||||
update_file "internal/cmd/version.go" \
|
||||
"Version = \"$CURRENT_VERSION\"" \
|
||||
"Version = \"$NEW_VERSION\""
|
||||
|
||||
# 2. Update npm-package/package.json
|
||||
echo " • npm-package/package.json"
|
||||
update_file "npm-package/package.json" \
|
||||
"\"version\": \"$CURRENT_VERSION\"" \
|
||||
"\"version\": \"$NEW_VERSION\""
|
||||
|
||||
# 3. Update CHANGELOG.md
|
||||
echo " • CHANGELOG.md"
|
||||
update_changelog "$NEW_VERSION"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Version updated to $NEW_VERSION${NC}"
|
||||
echo ""
|
||||
|
||||
# Show diff
|
||||
echo "Changed files:"
|
||||
git diff --stat
|
||||
echo ""
|
||||
|
||||
# Verify versions match
|
||||
echo "Verifying version consistency..."
|
||||
VERSION_GO=$(grep 'Version = ' internal/cmd/version.go | sed 's/.*"\(.*\)".*/\1/')
|
||||
VERSION_NPM=$(grep '"version"' npm-package/package.json | head -1 | sed 's/.*"\([0-9.]*\)".*/\1/')
|
||||
|
||||
if [ "$VERSION_GO" = "$NEW_VERSION" ] && [ "$VERSION_NPM" = "$NEW_VERSION" ]; then
|
||||
echo -e "${GREEN}✓ All versions match: $NEW_VERSION${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Version mismatch detected!${NC}"
|
||||
echo " version.go: $VERSION_GO"
|
||||
echo " package.json: $VERSION_NPM"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Auto-install if requested
|
||||
if [ "$AUTO_INSTALL" = true ]; then
|
||||
echo "Rebuilding and installing gt..."
|
||||
GOPATH_BIN="$(go env GOPATH)/bin"
|
||||
|
||||
if ! go build -o /tmp/gt-new ./cmd/gt; then
|
||||
echo -e "${RED}✗ go build failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Codesign on macOS
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
xattr -cr /tmp/gt-new 2>/dev/null
|
||||
codesign -f -s - /tmp/gt-new 2>/dev/null
|
||||
echo -e "${GREEN}✓ gt codesigned for macOS${NC}"
|
||||
fi
|
||||
|
||||
cp /tmp/gt-new "$GOPATH_BIN/gt"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
codesign -f -s - "$GOPATH_BIN/gt" 2>/dev/null
|
||||
fi
|
||||
rm -f /tmp/gt-new
|
||||
|
||||
echo -e "${GREEN}✓ gt installed to $GOPATH_BIN/gt${NC}"
|
||||
|
||||
# Verify
|
||||
INSTALLED_VERSION=$("$GOPATH_BIN/gt" version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||
if [ "$INSTALLED_VERSION" = "$NEW_VERSION" ]; then
|
||||
echo -e "${GREEN}✓ Verified: gt version $INSTALLED_VERSION${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ gt reports $INSTALLED_VERSION (expected $NEW_VERSION)${NC}"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Auto-commit if requested
|
||||
if [ "$AUTO_COMMIT" = true ]; then
|
||||
echo "Creating git commit..."
|
||||
|
||||
git add internal/cmd/version.go \
|
||||
npm-package/package.json
|
||||
|
||||
if [ -f "CHANGELOG.md" ]; then
|
||||
git add CHANGELOG.md
|
||||
fi
|
||||
|
||||
git commit -m "chore: Bump version to $NEW_VERSION
|
||||
|
||||
Updated all component versions:
|
||||
- gt CLI: $CURRENT_VERSION → $NEW_VERSION
|
||||
- npm package: $CURRENT_VERSION → $NEW_VERSION
|
||||
|
||||
Generated by scripts/bump-version.sh"
|
||||
|
||||
echo -e "${GREEN}✓ Commit created${NC}"
|
||||
echo ""
|
||||
|
||||
# Auto-tag if requested
|
||||
if [ "$AUTO_TAG" = true ]; then
|
||||
echo "Creating git tag v$NEW_VERSION..."
|
||||
git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
|
||||
echo -e "${GREEN}✓ Tag created${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Auto-push if requested
|
||||
if [ "$AUTO_PUSH" = true ]; then
|
||||
echo "Pushing to origin..."
|
||||
git push origin main
|
||||
git push origin "v$NEW_VERSION"
|
||||
echo -e "${GREEN}✓ Pushed to origin${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}Release v$NEW_VERSION initiated!${NC}"
|
||||
echo "GitHub Actions will build artifacts in ~5-10 minutes."
|
||||
echo "Monitor: https://github.com/steveyegge/gastown/actions"
|
||||
elif [ "$AUTO_TAG" = true ]; then
|
||||
echo "Next steps:"
|
||||
echo " git push origin main"
|
||||
echo " git push origin v$NEW_VERSION"
|
||||
else
|
||||
echo "Next steps:"
|
||||
echo " git push origin main"
|
||||
echo " git tag -a v$NEW_VERSION -m 'Release v$NEW_VERSION'"
|
||||
echo " git push origin v$NEW_VERSION"
|
||||
fi
|
||||
else
|
||||
echo "Review the changes above."
|
||||
echo ""
|
||||
echo "To commit and release:"
|
||||
echo " $0 $NEW_VERSION --commit --tag --push --install"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user