#!/bin/bash
set -e
# Create GitHub Release Script
# Builds release assets and creates GitHub release from an existing tag
# Usage: ./script/create-github-release v1.0.0-beta.1
VERSION=$1
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
error() {
echo -e "${RED}Error: $1${NC}" >&2
exit 1
}
info() {
echo -e "${GREEN}$1${NC}"
}
warn() {
echo -e "${YELLOW}$1${NC}"
}
debug() {
echo -e "${BLUE}$1${NC}"
}
# Cleanup function - called on exit (success or failure)
cleanup() {
local exit_code=$?
# Return to original branch/commit if we changed it
if [ -n "$CURRENT_REF" ] && [ -n "$CHECKED_OUT_TAG" ]; then
if ! git checkout "$CURRENT_REF" >/dev/null 2>&1; then
warn "Failed to return to ${CURRENT_REF}. You may need to manually checkout your branch."
fi
fi
# Clean up release artifacts directory
if [ -d "$RELEASE_DIR" ]; then
rm -rf "$RELEASE_DIR"
fi
# If we're exiting with an error, inform the user
if [ $exit_code -ne 0 ]; then
warn "Release creation failed. Cleanup completed."
fi
}
# Register cleanup function to run on exit
trap cleanup EXIT
# Check if version argument is provided
if [ -z "$VERSION" ]; then
error "Version argument required.\nUsage: $0 v1.0.0-beta.1"
fi
# Add 'v' prefix if not present
if [[ ! $VERSION =~ ^v ]]; then
VERSION="v${VERSION}"
fi
info "Creating GitHub release for ${VERSION}..."
# Check if tag exists
if ! git rev-parse "$VERSION" >/dev/null 2>&1; then
error "Tag $VERSION does not exist locally. Run ./script/tag-release first."
fi
# Check if gh CLI is installed
if ! command -v gh &> /dev/null; then
error "GitHub CLI (gh) is not installed. Install it from https://cli.github.com/"
fi
# Check if authenticated with gh
if ! gh auth status &> /dev/null; then
error "Not authenticated with GitHub CLI. Run: gh auth login"
fi
# Save current branch/commit to return to later
CURRENT_REF=$(git rev-parse --abbrev-ref HEAD)
if [ "$CURRENT_REF" == "HEAD" ]; then
# We're in detached HEAD state, save the commit
CURRENT_REF=$(git rev-parse HEAD)
fi
# Create temporary directory for release artifacts
RELEASE_DIR="release-artifacts"
rm -rf "$RELEASE_DIR"
mkdir -p "$RELEASE_DIR"
# Checkout the tag
info "Checking out tag ${VERSION}..."
CHECKED_OUT_TAG=""
if ! git checkout "$VERSION"; then
error "Failed to checkout tag ${VERSION}"
fi
CHECKED_OUT_TAG="$VERSION"
# Install dependencies and build
info "Installing dependencies..."
npm ci --quiet
info "Building project..."
npm run build
# Create tarball with essential files
info "Creating release tarball..."
TARBALL_NAME="aic-mcp-server-${VERSION}.tar.gz"
tar -czf "${RELEASE_DIR}/${TARBALL_NAME}" \
dist/ \
package.json \
package-lock.json \
README.md \
LICENSE
# Generate checksums
info "Generating checksums..."
cd "$RELEASE_DIR"
shasum -a 256 "$TARBALL_NAME" > SHA256SUMS.txt
cd ..
# Return to previous branch/commit (will also be done by cleanup trap)
info "Returning to ${CURRENT_REF}..."
if ! git checkout "$CURRENT_REF"; then
error "Failed to return to ${CURRENT_REF}"
fi
CHECKED_OUT_TAG="" # Clear flag since we've returned
# Determine if this is a pre-release
# Per semver 2.0.0: any version with a hyphen followed by identifiers is a pre-release
# Examples: v1.0.0-alpha, v1.0.0-beta.1, v1.0.0-rc.2, v1.0.0-pre.1
PRERELEASE_FLAG=""
if [[ $VERSION =~ -[a-zA-Z] ]]; then
PRERELEASE_FLAG="--prerelease"
info "Detected pre-release version (will mark as pre-release in GitHub)"
fi
# Create GitHub release
info "Creating GitHub release..."
gh release create "$VERSION" \
--repo pingidentity/aic-mcp-server \
--title "$VERSION" \
--generate-notes \
$PRERELEASE_FLAG \
"${RELEASE_DIR}/${TARBALL_NAME}" \
"${RELEASE_DIR}/SHA256SUMS.txt"
info "✓ Successfully created GitHub release ${VERSION}"
echo ""
info "Release URL:"
gh release view "$VERSION" --repo pingidentity/aic-mcp-server --web
echo ""