Skip to main content
Glama
publish.shโ€ข7.93 kB
#!/bin/bash # A comprehensive script to automate versioning, building, and publishing of a Node.js project. set -e # Exit on any error # --- Configuration --- # Your primary git branch MAIN_BRANCH="main" DOCKER_HUB_USERNAME="hexsleeves" DOCKER_HUB_REPO="tailscale-mcp-server" # --- Colors for output --- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # --- Helper Functions --- print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" exit 1 } prompt_yes_no() { local prompt="$1" local response while true; do read -p "$prompt (y/n): " response case $response in [Yy]*) return 0 ;; [Nn]*) return 1 ;; *) echo "Please answer yes (y) or no (n)." ;; esac done } # --- Package & Git Info Functions --- get_current_version() { bun -p "require('./package.json').version" } get_package_name() { bun -p "require('./package.json').name" } get_github_owner() { # Tries to automatically determine the GitHub user/org from the git remote URL local remote_url remote_url=$(git remote get-url origin 2>/dev/null) || return # Extracts 'user' from 'git@github.com:user/repo.git' or 'https://github.com/user/repo.git' echo "$remote_url" | sed -n -e 's#.*github.com[:/]\([^/]*\)/.*#\1#p' } # --- Core Workflow Functions --- bump_version() { local bump_type="$1" local new_version if [ "$bump_type" == "custom" ]; then read -p "Enter the custom version number: " new_version npm version "$new_version" --no-git-tag-version else # Use npm version to bump and capture the new version new_version=$(npm version "$bump_type" --no-git-tag-version | sed 's/v//') fi print_success "Version bumped to $new_version" # Commit the version change print_status "Committing version bump..." git add package.json package-lock.json git commit -m "chore: bump version to $new_version" # Create git tag print_status "Creating git tag v$new_version..." git tag "v$new_version" echo "$new_version" } publish_npm() { local version="$1" print_status "Preparing to publish to npm..." if prompt_yes_no "Run 'bun run build' first?"; then bun run build fi if prompt_yes_no "Run tests before publishing?"; then bun test fi if prompt_yes_no "Ready to publish version $version to npm?"; then bun publish --access public print_success "Published to npm successfully!" else print_warning "NPM publish aborted by user." fi } build_docker() { local version="$1" local docker_name="$DOCKER_HUB_USERNAME/$DOCKER_HUB_REPO" print_status "Building Docker image: $docker_name:$version" docker build -t "$docker_name:$version" -t "$docker_name:latest" . print_success "Built Docker image: $docker_name:$version" } publish_docker() { local version="$1" local package_name="$2" local docker_name docker_name="$DOCKER_HUB_USERNAME/$DOCKER_HUB_REPO" build_docker "$version" if prompt_yes_no "Push image '$docker_name' to Docker Hub?"; then print_status "Pushing to Docker Hub: $docker_name:$version..." docker push "$docker_name:$version" print_status "Pushing to Docker Hub: $docker_name:latest..." docker push "$docker_name:latest" print_success "Published to Docker Hub successfully!" else print_warning "Docker Hub push aborted by user." fi } publish_ghcr() { local version="$1" local package_name="$2" local docker_name local github_owner local ghcr_image docker_name="$DOCKER_HUB_USERNAME/$DOCKER_HUB_REPO" github_owner=$(get_github_owner) if [ -z "$github_owner" ]; then print_warning "Could not determine GitHub owner from git remote." read -p "Enter GitHub username/organization: " github_owner if [ -z "$github_owner" ]; then print_error "GitHub owner is required for GHCR publish." fi else print_status "Detected GitHub owner: $github_owner" fi lowercase_github_owner=$(echo "$github_owner" | tr '[:upper:]' '[:lower:]') ghcr_image="ghcr.io/$lowercase_github_owner/$DOCKER_HUB_REPO" print_status "Tagging image for GHCR: $ghcr_image:$version" docker tag "$docker_name:latest" "$ghcr_image:$version" docker tag "$docker_name:latest" "$ghcr_image:latest" if prompt_yes_no "Push image to GitHub Container Registry?"; then print_status "Pushing to GHCR..." docker push "$ghcr_image:$version" docker push "$ghcr_image:latest" print_success "Published to GitHub Container Registry successfully!" else print_warning "GHCR push aborted by user." fi } # --- Main Script Logic --- main() { print_status "๐Ÿš€ Starting publish workflow..." # --- Pre-flight Checks --- if ! git rev-parse --git-dir >/dev/null 2>&1; then print_error "Not a git repository. Aborting." fi if ! git diff-index --quiet HEAD --; then print_warning "You have uncommitted changes." if ! prompt_yes_no "Continue anyway?"; then print_error "Aborted by user." fi fi local current_version local package_name current_version=$(get_current_version) package_name=$(get_package_name) print_status "Package: $package_name" print_status "Current version: $current_version" # --- Version Bumping --- local new_version="$current_version" local bump_type="" echo "" print_status "Select a version bump type:" # Pre-calculate version bumps to avoid repeated npx semver calls local patch_ver minor_ver major_ver patch_ver=$(npx semver "$current_version" -i patch) minor_ver=$(npx semver "$current_version" -i minor) major_ver=$(npx semver "$current_version" -i major) local options=( "patch ($patch_ver)" "minor ($minor_ver)" "major ($major_ver)" "prerelease" "custom" "skip" ) PS3="Your choice: " # Prompt for the select menu select opt in "${options[@]}"; do case $opt in "patch"*) bump_type="patch" break ;; "minor"*) bump_type="minor" break ;; "major"*) bump_type="major" break ;; "prerelease") bump_type="prerelease" break ;; "custom") bump_type="custom" break ;; "skip") bump_type="skip" break ;; *) print_warning "Invalid option. Please try again." ;; esac done if [[ -n "$bump_type" && "$bump_type" != "skip" ]]; then new_version=$(bump_version "$bump_type") else print_status "Skipping version bump. Using current version: $current_version" fi echo "" print_status "Working with version: $new_version" # --- Publishing Options --- local did_publish_docker=false echo "" if prompt_yes_no "Publish to npm?"; then publish_npm "$new_version" fi echo "" if prompt_yes_no "Build and publish Docker image?"; then # We only need to build the Docker image once publish_docker "$new_version" "$package_name" did_publish_docker=true fi echo "" if prompt_yes_no "Publish to GitHub Container Registry?"; then if ! $did_publish_docker; then print_warning "Docker image was not built in the previous step." if prompt_yes_no "Build it now?"; then build_docker "$new_version" else print_error "Cannot publish to GHCR without a built image." fi fi publish_ghcr "$new_version" "$package_name" fi # --- Final Git Push --- if [ "$new_version" != "$current_version" ]; then echo "" if prompt_yes_no "Push git commits and tags to origin?"; then git push origin "$MAIN_BRANCH" git push origin "v$new_version" print_success "Git changes and tags pushed!" fi fi echo "" print_success "๐ŸŽ‰ Publish workflow completed!" print_status "Final version: $new_version" } # Run the main function with all passed arguments main "$@"

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/HexSleeves/tailscale-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server