diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 49fb13b..68f914d 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -1,8 +1,11 @@ -#!/bin/bash -# Build release binaries for distribution -# Creates: dist/mt5-quant-{platform}.tar.gz +#!/usr/bin/env bash +# Build release binary and package it for distribution +# Creates: dist/mcp-mt5-quant-{platform}.tar.gz +# +# Usage: +# bash scripts/build-release.sh -set -e +set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" @@ -10,16 +13,17 @@ PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" cd "$PROJECT_ROOT" VERSION=$(grep -E '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') -echo "=== Building MCP-MT5-Quant v${VERSION} ===" +echo "=== Building mt5-quant v${VERSION} ===" echo "" # Clean previous builds rm -rf "$PROJECT_ROOT/dist" mkdir -p "$PROJECT_ROOT/dist" -# Build current platform -echo "Building for current platform..." +# Build release binary +echo "Building release binary..." RUSTFLAGS="-D warnings" cargo build --release +echo "" # Detect platform UNAME=$(uname -s) @@ -30,43 +34,46 @@ if [[ "$UNAME" == "Darwin" ]]; then elif [[ "$UNAME" == "Linux" ]]; then PLATFORM="linux-${ARCH}" else - PLATFORM="unknown" + PLATFORM="unknown-${ARCH}" fi PACKAGE_NAME="mcp-mt5-quant-${PLATFORM}" PACKAGE_DIR="$PROJECT_ROOT/dist/${PACKAGE_NAME}" echo "Packaging for ${PLATFORM}..." -mkdir -p "$PACKAGE_DIR" +mkdir -p "$PACKAGE_DIR/docs" -# Copy binary +# Binary cp "$PROJECT_ROOT/target/release/mt5-quant" "$PACKAGE_DIR/" +chmod +x "$PACKAGE_DIR/mt5-quant" -# Copy config template +# Config template mkdir -p "$PACKAGE_DIR/config" cp "$PROJECT_ROOT/config/mt5-quant.example.yaml" "$PACKAGE_DIR/config/" -# Copy docs -cp "$PROJECT_ROOT/README.md" "$PACKAGE_DIR/" -cp "$PROJECT_ROOT/docs/WINDSURF.md" "$PACKAGE_DIR/WINDSURF_SETUP.md" -cp "$PROJECT_ROOT/CLAUDE.md" "$PACKAGE_DIR/" +# Documentation +cp "$PROJECT_ROOT/README.md" "$PACKAGE_DIR/" +cp "$PROJECT_ROOT/docs/QUICKSTART.md" "$PACKAGE_DIR/docs/" +cp "$PROJECT_ROOT/docs/CLAUDE.md" "$PACKAGE_DIR/docs/" +cp "$PROJECT_ROOT/docs/CURSOR.md" "$PACKAGE_DIR/docs/" +cp "$PROJECT_ROOT/docs/VSCODE.md" "$PACKAGE_DIR/docs/" +cp "$PROJECT_ROOT/docs/WINDSURF.md" "$PACKAGE_DIR/docs/" # Create tarball cd "$PROJECT_ROOT/dist" tar -czf "${PACKAGE_NAME}.tar.gz" "$PACKAGE_NAME" +rm -rf "$PACKAGE_NAME" echo "" -echo "=== Build Complete ===" +echo "=== Build complete ===" echo "" -echo "Package: dist/${PACKAGE_NAME}.tar.gz" -echo "Binary: mt5-quant" -echo "Size: $(du -h "${PACKAGE_NAME}.tar.gz" | cut -f1)" +echo "Package : dist/${PACKAGE_NAME}.tar.gz" +echo "Size : $(du -h "${PACKAGE_NAME}.tar.gz" | cut -f1)" echo "" echo "Contents:" -tar -tzf "${PACKAGE_NAME}.tar.gz" | head -10 +tar -tzf "${PACKAGE_NAME}.tar.gz" echo "" -echo "To install:" +echo "Install:" echo " tar -xzf ${PACKAGE_NAME}.tar.gz" -echo " cd ${PACKAGE_NAME}" -echo " sudo cp mt5-quant /usr/local/bin/" +echo " sudo cp ${PACKAGE_NAME}/mt5-quant /usr/local/bin/" echo " mt5-quant --help" diff --git a/scripts/build-rust.sh b/scripts/build-rust.sh index b84669b..846673d 100755 --- a/scripts/build-rust.sh +++ b/scripts/build-rust.sh @@ -1,32 +1,25 @@ -#!/bin/bash -# Build MT5-Quant Rust MCP Server +#!/usr/bin/env bash +# Build MT5-Quant release binary # Output: target/release/mt5-quant -set -e +set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" cd "$PROJECT_ROOT" -echo "=== MT5-Quant Rust Build ===" -echo "Project root: $PROJECT_ROOT" +echo "=== MT5-Quant build ===" +echo "Root: $PROJECT_ROOT" echo "" -echo "Building release binary..." cargo build --release echo "" -echo "=== Build Complete ===" +echo "=== Done ===" echo "" -echo "Executable location:" ls -lh "$PROJECT_ROOT/target/release/mt5-quant" - echo "" -echo "To test:" -echo " ./target/release/mt5-quant --help" -echo "" -echo "To install for Windsurf:" -echo " Update ~/.windsurf/config.yaml:" -echo " command: $PROJECT_ROOT/target/release/mt5-quant" +echo "Run: ./target/release/mt5-quant --help" +echo "Install: cargo install --path . --force" echo "" diff --git a/scripts/release.sh b/scripts/release.sh index 123bf17..08a2660 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -7,6 +7,7 @@ # bash scripts/release.sh major # 1.31.0 → 2.0.0 # bash scripts/release.sh 1.32.0 # explicit version # bash scripts/release.sh v1.32.0 # with v prefix +# bash scripts/release.sh patch --yes # non-interactive (CI / Claude Code) set -euo pipefail cd "$(dirname "$0")/.." @@ -18,44 +19,54 @@ warn() { echo -e "${YELLOW}⚠ $*${NC}"; } die() { echo -e "${RED}✗ $*${NC}" >&2; exit 1; } hr() { echo -e "${BLUE}────────────────────────────────────────${NC}"; } -# ── Prerequisites ───────────────────────────────────────────────────────────── +# ── Argument parsing ─────────────────────────────────────────────────────────── -command -v cargo >/dev/null 2>&1 || die "cargo not found" +bump="${1:-patch}" +AUTO_YES=false +if [[ "${2:-}" == "--yes" || "${2:-}" == "-y" || "${CI:-}" == "true" ]]; then + AUTO_YES=true +fi + +# ── Prerequisites ────────────────────────────────────────────────────────────── + +command -v cargo >/dev/null 2>&1 || die "cargo not found" command -v python3 >/dev/null 2>&1 || die "python3 not found" -# ── Current version ─────────────────────────────────────────────────────────── +# ── Current version ──────────────────────────────────────────────────────────── current=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') [[ -n "$current" ]] || die "Could not parse version from Cargo.toml" info "Current version: ${BOLD}$current${NC}" -# ── Compute new version ─────────────────────────────────────────────────────── +# ── Compute new version ──────────────────────────────────────────────────────── -bump="${1:-patch}" IFS='.' read -r major minor patch_v <<< "$current" case "$bump" in - major) new="${major+1}.0.0"; new="$((major + 1)).0.0" ;; - minor) new="${major}.$((minor + 1)).0" ;; - patch) new="${major}.${minor}.$((patch_v + 1))" ;; - v*.*.*) new="${bump#v}" ;; - *.*.*) new="$bump" ;; - *) die "Usage: $0 [patch|minor|major|X.Y.Z]" ;; + major) new="$((major + 1)).0.0" ;; + minor) new="${major}.$((minor + 1)).0" ;; + patch) new="${major}.${minor}.$((patch_v + 1))" ;; + v*.*.*) new="${bump#v}" ;; + *.*.*) new="$bump" ;; + *) die "Usage: $0 [patch|minor|major|X.Y.Z] [--yes]" ;; esac -# Validate semver [[ "$new" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || die "Invalid version: $new" hr info "Releasing: ${BOLD}$current → $new${NC}" hr -# ── Confirm ─────────────────────────────────────────────────────────────────── +# ── Confirm ──────────────────────────────────────────────────────────────────── -read -rp "Proceed with release v${new}? [y/N] " confirm -[[ "$confirm" =~ ^[Yy]$ ]] || die "Aborted" +if [[ "$AUTO_YES" == false ]]; then + read -rp "Proceed with release v${new}? [y/N] " confirm + [[ "$confirm" =~ ^[Yy]$ ]] || die "Aborted" +else + info "Auto-confirmed (--yes)" +fi -# ── Check git state ─────────────────────────────────────────────────────────── +# ── Check git state ──────────────────────────────────────────────────────────── info "Checking git state..." if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then @@ -64,13 +75,12 @@ fi current_branch=$(git rev-parse --abbrev-ref HEAD) info "Branch: $current_branch" -# Check tag doesn't already exist if git rev-parse "v${new}" >/dev/null 2>&1; then die "Tag v${new} already exists" fi ok "Git state clean" -# ── 1. Bump Cargo.toml ──────────────────────────────────────────────────────── +# ── 1. Bump Cargo.toml ───────────────────────────────────────────────────────── info "Bumping Cargo.toml..." if [[ "$(uname)" == "Darwin" ]]; then @@ -78,16 +88,14 @@ if [[ "$(uname)" == "Darwin" ]]; then else sed -i "s/^version = \"${current}\"/version = \"${new}\"/" Cargo.toml fi - -# Update Cargo.lock cargo metadata --no-deps --format-version 1 >/dev/null 2>&1 || true ok "Cargo.toml → $new" -# ── 2. Update server.json ───────────────────────────────────────────────────── +# ── 2. Update server.json ────────────────────────────────────────────────────── info "Updating server.json..." NEW_VERSION="$new" python3 - <<'PYEOF' -import json, os, re, sys +import json, os, re version = os.environ['NEW_VERSION'] @@ -98,7 +106,6 @@ data['version'] = version for pkg in data.get('packages', []): pkg['version'] = version - # Update download URL to point at new version tag if 'identifier' in pkg: pkg['identifier'] = re.sub( r'/v[0-9]+\.[0-9]+\.[0-9]+/', @@ -114,9 +121,9 @@ with open('server.json', 'w') as f: print(f" server.json version={version}, identifier URL updated") PYEOF -ok "server.json → $new (SHA256 updated by CI)" +ok "server.json → $new (SHA256 set by CI)" -# ── 3. Generate CHANGELOG entry ─────────────────────────────────────────────── +# ── 3. Generate CHANGELOG entry ──────────────────────────────────────────────── info "Generating CHANGELOG entry..." prev_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "") @@ -138,7 +145,6 @@ today=$(date +%Y-%m-%d) } > /tmp/release_entry.md if [[ -f CHANGELOG.md ]]; then - # Insert after the first header line tmp=$(mktemp) head -1 CHANGELOG.md > "$tmp" echo "" >> "$tmp" @@ -146,22 +152,18 @@ if [[ -f CHANGELOG.md ]]; then tail -n +2 CHANGELOG.md >> "$tmp" mv "$tmp" CHANGELOG.md else - { - echo "# Changelog" - echo "" - cat /tmp/release_entry.md - } > CHANGELOG.md + { echo "# Changelog"; echo ""; cat /tmp/release_entry.md; } > CHANGELOG.md fi rm -f /tmp/release_entry.md ok "CHANGELOG.md updated" -# ── 4. Verify build compiles ────────────────────────────────────────────────── +# ── 4. Verify build ──────────────────────────────────────────────────────────── info "Verifying build (cargo check)..." cargo check --quiet 2>&1 || die "cargo check failed — fix errors before releasing" ok "Build check passed" -# ── 5. Commit ───────────────────────────────────────────────────────────────── +# ── 5. Commit ────────────────────────────────────────────────────────────────── info "Creating release commit..." git add Cargo.toml Cargo.lock server.json CHANGELOG.md @@ -172,20 +174,56 @@ git commit -m "release: v${new} - CHANGELOG.md updated" ok "Release commit created" -# ── 6. Tag ──────────────────────────────────────────────────────────────────── +# ── 6. Tag ───────────────────────────────────────────────────────────────────── info "Creating annotated tag v${new}..." git tag -a "v${new}" -m "Release v${new}" ok "Tagged v${new}" -# ── 7. Push ─────────────────────────────────────────────────────────────────── +# ── 7. Push (rebase if remote has new commits from CI) ───────────────────────── info "Pushing to GitHub..." -git push origin "$current_branch" -git push origin "v${new}" +if ! git push origin "$current_branch" 2>/dev/null; then + warn "Push rejected — rebasing on remote (CI may have committed SHA256)..." + git fetch origin "$current_branch" + + # Resolve server.json conflict automatically: keep our version + if ! git rebase "origin/${current_branch}"; then + if git diff --name-only --diff-filter=U | grep -q "server.json"; then + python3 - <<'PYEOF' +import re +with open('server.json') as f: + raw = f.read() +resolved = re.sub( + r'<<<<<<< HEAD.*?=======\n(.*?)>>>>>>> [^\n]+\n', + r'\1', + raw, + flags=re.DOTALL +) +with open('server.json', 'w') as f: + f.write(resolved) +PYEOF + git add server.json + GIT_EDITOR=true git rebase --continue + else + git rebase --abort + die "Rebase failed with unexpected conflicts — push manually" + fi + fi + + git push origin "$current_branch" +fi + +# Push tag (delete and re-push if rebase moved the commit) +git push origin "v${new}" 2>/dev/null || { + git push origin ":refs/tags/v${new}" 2>/dev/null || true + git tag -f -a "v${new}" -m "Release v${new}" + git push origin "v${new}" +} + ok "Pushed — GitHub Actions triggered" -# ── Done ────────────────────────────────────────────────────────────────────── +# ── Done ─────────────────────────────────────────────────────────────────────── hr echo "" diff --git a/scripts/setup.sh b/scripts/setup.sh index 3ff7711..516d616 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -14,7 +14,7 @@ # - Windsurf : ~/.codeium/windsurf/mcp_config.json (JSON, mcpServers) # - Cursor : ~/.cursor/mcp.json (JSON, mcpServers) # - VS Code : .vscode/mcp.json (JSON, servers - not mcpServers) -# - Antigravity : mcp_config.json via UI (JSON, mcpServers) +# - Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json # # Previous installations are auto-detected and uninstalled before re-registering. @@ -1201,7 +1201,7 @@ _register_all_mcp_platforms() { echo " - Windsurf: Edit ~/.codeium/windsurf/mcp_config.json" echo " - Cursor: Edit ~/.cursor/mcp.json" echo " - VS Code: Edit .vscode/mcp.json (workspace) or use MCP: Add Server command" - echo " - Antigravity:Use Agent panel → MCP Servers → Manage → Edit configuration" + echo " - Claude Desktop: Edit ~/Library/Application Support/Claude/claude_desktop_config.json" echo "" return fi