#!/bin/bash
set -e
# Usage: ./release.sh <version> [npm-tag] [--dry-run]
VERSION=$1
DRY_RUN=false
NPM_TAG_SPECIFIED=false
NPM_TAG="latest"
# Validate version format
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+\.[0-9]+)?$ ]]; then
echo "❌ Invalid version format: $VERSION"
echo "Version must be in format: x.y.z or x.y.z-tag.n (e.g., 1.4.0 or 1.4.0-beta.3)"
exit 1
fi
# Set default tag based on version format
if [[ "$VERSION" =~ -beta ]]; then
NPM_TAG="beta"
elif [[ "$VERSION" =~ -alpha ]]; then
NPM_TAG="alpha"
elif [[ "$VERSION" =~ -rc ]]; then
NPM_TAG="rc"
elif [[ "$VERSION" =~ -experimental ]]; then
NPM_TAG="experimental"
fi
# Check for arguments and set flags
for arg in "$@"; do
if [[ "$arg" == "--dry-run" ]]; then
DRY_RUN=true
elif [[ "$arg" != "$VERSION" && "$arg" != "--dry-run" ]]; then
# If argument is not the version and not --dry-run, treat it as the npm tag
NPM_TAG="$arg"
NPM_TAG_SPECIFIED=true
fi
done
if [ -z "$VERSION" ]; then
echo "Usage: $0 <version> [npm-tag] [--dry-run]"
exit 1
fi
# Detect current branch
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Enforce branch/tag policy (customize as needed)
if [[ "$BRANCH" == "main" && "$NPM_TAG" != "latest" && "$NPM_TAG_SPECIFIED" == false ]]; then
echo "⚠️ Warning: Publishing a non-latest tag from main branch."
echo "Continue? (y/n)"
read -r CONTINUE
if [[ "$CONTINUE" != "y" ]]; then
echo "❌ Release cancelled."
exit 1
fi
fi
if [[ "$BRANCH" != "main" && "$NPM_TAG" == "latest" ]]; then
echo "⚠️ Warning: Publishing with tag '$NPM_TAG' from non-main branch."
echo "Continue? (y/n)"
read -r CONTINUE
if [[ "$CONTINUE" != "y" ]]; then
echo "❌ Release cancelled."
exit 1
fi
fi
run() {
if $DRY_RUN; then
echo "[dry-run] $*"
else
eval "$@"
fi
}
# Version update
echo ""
echo "🔧 Setting version to $VERSION..."
run "npm version \"$VERSION\" --no-git-tag-version"
# README update
echo ""
echo "📝 Updating version in README.md..."
# Update version references in code examples using extended regex for precise semver matching
run "sed -i '' -E 's/@[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+\.[0-9]+)?(-[a-zA-Z0-9]+\.[0-9]+)*(-[a-zA-Z0-9]+)?/@'"$VERSION"'/g' README.md"
# Update URL-encoded version references in shield links
echo "📝 Updating version in README.md shield links..."
run "sed -i '' -E 's/npm%3Axcodebuildmcp%40[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+\.[0-9]+)?(-[a-zA-Z0-9]+\.[0-9]+)*(-[a-zA-Z0-9]+)?/npm%3Axcodebuildmcp%40'"$VERSION"'/g' README.md"
echo ""
echo "📝 Updating version in TOOL_OPTIONS.md..."
run "sed -i '' -E 's/@[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+\.[0-9]+)?(-[a-zA-Z0-9]+\.[0-9]+)*(-[a-zA-Z0-9]+)?/@'"$VERSION"'/g' TOOL_OPTIONS.md"
# Build
echo ""
echo "🛠 Running build..."
run "npm run build"
# Git operations
echo ""
echo "📦 Committing changes..."
run "git add ."
run "git commit -m \"Release v$VERSION\""
run "git tag \"v$VERSION\""
echo ""
echo "🚀 Pushing to origin..."
run "git push origin $BRANCH --tags"
echo "📦 Creating GitHub release..."
if [[ "$NPM_TAG" == "beta" || "$NPM_TAG" == "alpha" || "$NPM_TAG" == "rc" || "$NPM_TAG" == "experimental" ]]; then
run "gh release create "v$VERSION" --generate-notes -t \"Release v$VERSION\" --prerelease"
else
run "gh release create "v$VERSION" --generate-notes -t \"Release v$VERSION\""
fi
# npm publish
echo ""
echo "📤 Publishing to npm with tag '$NPM_TAG'..."
run "npm publish --tag $NPM_TAG"
# Completion message
echo ""
echo "✅ Release v$VERSION complete!"
echo "📝 Don't forget to update the changelog"
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/SampsonKY/XcodeBuildMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server