name: Release Packages
on:
push:
tags:
- "v*" # Release all packages with same version
- "tauri-plugin-mcp-bridge/v*" # Release only the plugin
- "mcp-server/v*" # Release only the server
jobs:
determine-packages:
name: Determine packages to release
runs-on: ubuntu-latest
outputs:
release-plugin: ${{ steps.check.outputs.plugin }}
release-server: ${{ steps.check.outputs.server }}
version: ${{ steps.check.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Extract version and check packages
id: check
run: |
TAG=${GITHUB_REF#refs/tags/}
# Check if we should release plugin
if [[ "$TAG" == "tauri-plugin-mcp-bridge/v"* ]]; then
VERSION=${TAG#tauri-plugin-mcp-bridge/v}
echo "plugin=true" >> $GITHUB_OUTPUT
echo "server=false" >> $GITHUB_OUTPUT
elif [[ "$TAG" == "mcp-server/v"* ]]; then
VERSION=${TAG#mcp-server/v}
echo "plugin=false" >> $GITHUB_OUTPUT
echo "server=true" >> $GITHUB_OUTPUT
else
# Generic version tag - release all packages
VERSION=${TAG#v}
echo "plugin=true" >> $GITHUB_OUTPUT
echo "server=true" >> $GITHUB_OUTPUT
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
test-plugin:
name: Test tauri-plugin-mcp-bridge
needs: determine-packages
if: needs.determine-packages.outputs.release-plugin == 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
cache: "npm"
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: Install dependencies
run: npm ci
- name: Build and test plugin
run: |
cd packages/tauri-plugin-mcp-bridge
npm run build
cargo test --all-features
cargo fmt -- --check
cargo clippy -- -D warnings
test-server:
name: Test @hypothesi/tauri-mcp-server
needs: determine-packages
if: needs.determine-packages.outputs.release-server == 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: ["24", "20"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Install server dependencies only
run: npm ci --workspace=@hypothesi/tauri-mcp-server --include-workspace-root
- name: Build and test server
run: |
npm run build --workspace=@hypothesi/tauri-mcp-server
npm run test:unit --workspace=@hypothesi/tauri-mcp-server
npx tsc --noEmit --project packages/mcp-server/tsconfig.json
release-plugin:
name: Release tauri-plugin-mcp-bridge
needs: [determine-packages, test-plugin]
if: needs.determine-packages.outputs.release-plugin == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"
registry-url: "https://registry.npmjs.org"
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: Install and update versions
run: |
npm ci
cd packages/tauri-plugin-mcp-bridge
sed -i.bak "s/^version = \".*\"/version = \"${{ needs.determine-packages.outputs.version }}\"/" Cargo.toml && rm Cargo.toml.bak
npm version ${{ needs.determine-packages.outputs.version }} --no-git-tag-version --allow-same-version
- name: Build
run: |
cd packages/tauri-plugin-mcp-bridge
npm run build
cargo build --release
- name: Publish to NPM
run: |
cd packages/tauri-plugin-mcp-bridge
npm publish --access public --provenance
continue-on-error: false
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
cd packages/tauri-plugin-mcp-bridge
cargo publish --token "${CARGO_REGISTRY_TOKEN}"
continue-on-error: false
release-server:
name: Release @hypothesi/tauri-mcp-server
needs: [determine-packages, test-server]
if: needs.determine-packages.outputs.release-server == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"
registry-url: "https://registry.npmjs.org"
- name: Install and update version
run: |
npm ci
cd packages/mcp-server
npm version ${{ needs.determine-packages.outputs.version }} --no-git-tag-version --allow-same-version
- name: Update server.json version
run: node packages/mcp-server/scripts/update-server-json-version.js ${{ needs.determine-packages.outputs.version }}
- name: Build
run: |
cd packages/mcp-server
npm run build
- name: Publish to NPM
run: |
cd packages/mcp-server
npm publish --access public --provenance
continue-on-error: false
create-release:
name: Create GitHub Release
needs: [determine-packages, release-plugin, release-server]
if: ${{ !cancelled() && (needs.release-plugin.result == 'success' || needs.release-server.result == 'success' || needs.release-plugin.result == 'skipped' || needs.release-server.result == 'skipped') }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Generate release notes
id: release_notes
run: |
VERSION=${{ needs.determine-packages.outputs.version }}
# Function to extract changelog section for a specific version
extract_changelog() {
local file=$1
local version=$2
# Extract content between "## [version]" and the next "## ["
# Skip "_No changes to this package._" entries
awk -v ver="$version" '
BEGIN { found=0 }
/^## \[/ { if (found) exit; if ($0 ~ "\\[" ver "\\]") { found=1; next } }
found && !/^## \[/ && !/^_No changes/ { print }
' "$file"
}
{
echo "notes<<EOF"
echo ""
if [[ "${{ needs.determine-packages.outputs.release-plugin }}" == "true" ]]; then
echo "## tauri-plugin-mcp-bridge"
echo ""
echo "[](https://crates.io/crates/tauri-plugin-mcp-bridge) [](https://www.npmjs.com/package/@hypothesi/tauri-plugin-mcp-bridge)"
echo ""
PLUGIN_CHANGES=$(extract_changelog "packages/tauri-plugin-mcp-bridge/CHANGELOG.md" "$VERSION")
if [[ -n "$PLUGIN_CHANGES" ]]; then
echo "$PLUGIN_CHANGES"
else
echo "_No changes to this package._"
fi
echo ""
fi
if [[ "${{ needs.determine-packages.outputs.release-server }}" == "true" ]]; then
echo "## @hypothesi/tauri-mcp-server"
echo ""
echo "[](https://www.npmjs.com/package/@hypothesi/tauri-mcp-server)"
echo ""
SERVER_CHANGES=$(extract_changelog "packages/mcp-server/CHANGELOG.md" "$VERSION")
if [[ -n "$SERVER_CHANGES" ]]; then
echo "$SERVER_CHANGES"
else
echo "_No changes to this package._"
fi
echo ""
fi
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.ref_name }}
name: "Release ${{ needs.determine-packages.outputs.version }}"
body: ${{ steps.release_notes.outputs.notes }}
draft: false
prerelease: false