[Compyle] Task cmgy4cp1t00ryq2i9vkmm3uma updates for codealive-mcp #53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Publish CodeAlive MCP Server | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| DOCKER_REGISTRY: ghcr.io | |
| DOCKER_USERNAME: ${{ github.actor }} | |
| DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| IMAGE_NAME: ghcr.io/codealive-ai/codealive-mcp | |
| permissions: | |
| id-token: write # Required for MCP Registry OIDC authentication | |
| contents: write # For creating tags and releases | |
| packages: write | |
| jobs: | |
| build-and-publish: | |
| name: Build, Test, and Publish MCP Server | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Fetch all history for version detection | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| cache: 'pip' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| pip install pytest pytest-asyncio pytest-mock pytest-cov jsonschema | |
| - name: Run tests | |
| run: | | |
| python -m pytest src/tests/ -v --cov=src --cov-report=term-missing --cov-report=xml --junitxml=junit/test-results.xml | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: pytest-results | |
| path: | | |
| junit/test-results.xml | |
| coverage.xml | |
| - name: Check for version change | |
| id: version-check | |
| run: | | |
| # Get current version from pyproject.toml | |
| CURRENT_VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/') | |
| echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT | |
| # Check if tag already exists | |
| if git tag -l "v$CURRENT_VERSION" | grep -q "v$CURRENT_VERSION"; then | |
| echo "version_changed=false" >> $GITHUB_OUTPUT | |
| echo "Tag v$CURRENT_VERSION already exists" | |
| else | |
| echo "version_changed=true" >> $GITHUB_OUTPUT | |
| echo "New version detected: $CURRENT_VERSION" | |
| fi | |
| - name: Update server.json version | |
| if: steps.version-check.outputs.version_changed == 'true' | |
| run: | | |
| python -c " | |
| import json | |
| with open('server.json', 'r') as f: | |
| data = json.load(f) | |
| version = '${{ steps.version-check.outputs.current_version }}' | |
| # Update top-level version | |
| data['version'] = version | |
| # Update all packages | |
| if 'packages' in data: | |
| for package in data['packages']: | |
| registry_type = package.get('registryType') | |
| # Update version field (required for all packages in 2025-09-29) | |
| package['version'] = version | |
| # Update identifier with new version tag | |
| if registry_type == 'oci': | |
| identifier = package.get('identifier', '') | |
| if ':' in identifier: | |
| base = identifier.rsplit(':', 1)[0] | |
| package['identifier'] = f'{base}:{version}' | |
| with open('server.json', 'w') as f: | |
| json.dump(data, f, indent=2) | |
| " | |
| - name: Validate server.json | |
| if: steps.version-check.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' | |
| run: | | |
| python - <<'PY' | |
| from textwrap import dedent | |
| exec( | |
| dedent( | |
| """ | |
| import json | |
| import sys | |
| import urllib.request | |
| from jsonschema import ValidationError, validate | |
| schema_url = "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json" | |
| try: | |
| with urllib.request.urlopen(schema_url, timeout=30) as response: | |
| schema = json.load(response) | |
| except Exception as exc: | |
| print(f"✗ Unable to download server.json schema: {exc}") | |
| sys.exit(1) | |
| try: | |
| with open('server.json', 'r') as f: | |
| data = json.load(f) | |
| except Exception as exc: | |
| print(f"✗ Failed to load server.json: {exc}") | |
| sys.exit(1) | |
| try: | |
| validate(instance=data, schema=schema) | |
| print('✓ server.json schema validation passed') | |
| except ValidationError as exc: | |
| print(f"✗ server.json schema validation failed: {exc.message}") | |
| sys.exit(1) | |
| has_packages = 'packages' in data and len(data['packages']) > 0 | |
| has_remotes = 'remotes' in data and len(data['remotes']) > 0 | |
| if not (has_packages or has_remotes): | |
| print('✗ Must have either packages or remotes configured') | |
| sys.exit(1) | |
| if has_packages: | |
| for idx, pkg in enumerate(data['packages']): | |
| registry_type = pkg.get('registryType') | |
| identifier = pkg.get('identifier') | |
| if registry_type not in ['npm', 'pypi', 'nuget', 'oci', 'mcpb']: | |
| print(f"✗ Package {idx}: Invalid registry type '{registry_type}'") | |
| sys.exit(1) | |
| print(f"✓ Package {idx}: {registry_type.upper()} -> {identifier}") | |
| if has_remotes: | |
| for idx, remote in enumerate(data['remotes']): | |
| remote_type = remote.get('type') | |
| url = remote.get('url') | |
| if remote_type not in ['sse', 'streamable-http']: | |
| print(f"✗ Remote {idx}: Invalid transport type '{remote_type}'") | |
| sys.exit(1) | |
| print(f"✓ Remote {idx}: {remote_type} -> {url}") | |
| print('✓ server.json validation passed (hybrid deployment)') | |
| """ | |
| ) | |
| ) | |
| PY | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}},value=${{ steps.version-check.outputs.current_version }},enable=${{ github.ref == 'refs/heads/main' && steps.version-check.outputs.version_changed == 'true' }} | |
| type=semver,pattern=v{{version}},value=${{ steps.version-check.outputs.current_version }},enable=${{ github.ref == 'refs/heads/main' && steps.version-check.outputs.version_changed == 'true' }} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.DOCKER_REGISTRY }} | |
| username: ${{ env.DOCKER_USERNAME }} | |
| password: ${{ env.DOCKER_PASSWORD }} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| file: ./Dockerfile | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: | | |
| ${{ steps.meta.outputs.labels }} | |
| io.modelcontextprotocol.server.name=io.github.CodeAlive-AI/codealive-mcp | |
| cache-from: type=gha | |
| cache-to: type=gha | |
| - name: Create git tag | |
| if: steps.version-check.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag "v${{ steps.version-check.outputs.current_version }}" | |
| git push origin "v${{ steps.version-check.outputs.current_version }}" | |
| - name: Install MCP Publisher CLI | |
| if: steps.version-check.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' | |
| run: | | |
| curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.1.0/mcp-publisher_1.1.0_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher | |
| chmod +x mcp-publisher | |
| - name: Login to MCP Registry (GitHub OIDC) | |
| if: steps.version-check.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' | |
| run: | | |
| ./mcp-publisher login github-oidc | |
| - name: Publish to MCP Registry | |
| if: steps.version-check.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' | |
| run: | | |
| ./mcp-publisher publish | |
| - name: Create GitHub Release | |
| if: steps.version-check.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: v${{ steps.version-check.outputs.current_version }} | |
| name: CodeAlive MCP v${{ steps.version-check.outputs.current_version }} | |
| body: | | |
| ## CodeAlive MCP Server v${{ steps.version-check.outputs.current_version }} | |
| ### 🚀 Hybrid Deployment Options | |
| **Docker Container (Local)** | |
| ```bash | |
| docker run --rm -i -e CODEALIVE_API_KEY=your-key ghcr.io/codealive-ai/codealive-mcp:v${{ steps.version-check.outputs.current_version }} | |
| ``` | |
| **MCP Registry** | |
| ```json | |
| { | |
| "name": "io.github.codealive-ai/codealive-mcp", | |
| "transport": { | |
| "type": "stdio", | |
| "command": "docker", | |
| "args": ["run", "--rm", "-i", "-e", "CODEALIVE_API_KEY=YOUR_API_KEY_HERE", "ghcr.io/codealive-ai/codealive-mcp:v${{ steps.version-check.outputs.current_version }}"] | |
| } | |
| } | |
| ``` | |
| **Remote HTTP (Zero Setup)** | |
| ```json | |
| { | |
| "transport": { | |
| "type": "http", | |
| "url": "https://mcp.codealive.ai/api" | |
| }, | |
| "headers": { | |
| "Authorization": "Bearer your-codealive-api-key" | |
| } | |
| } | |
| ``` | |
| draft: false | |
| prerelease: false |