chore(release): bump version to 0.3.2 #43
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| env: | |
| PYTHON_VERSION: "3.13" | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| build_dist: | |
| name: Build sdist/wheel and verify version | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - uses: astral-sh/setup-uv@v6 | |
| with: | |
| version: latest | |
| - name: Set up Python | |
| run: uv python install ${{ env.PYTHON_VERSION }} | |
| - name: Extract version from tag | |
| id: ver | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
| echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| - name: Verify version matches pyproject.toml | |
| run: | | |
| PROJECT_VERSION=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])") | |
| test "$PROJECT_VERSION" = "${{ steps.ver.outputs.VERSION }}" | |
| - name: Clean dist directory | |
| run: rm -rf dist/ | |
| - name: Build package | |
| run: uv build --no-sources | |
| - name: Upload dist artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/* | |
| publish_pypi: | |
| name: Publish to PyPI | |
| needs: build_dist | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| password: ${{ secrets.PYPI_API_TOKEN }} | |
| docker_build_by_platform: | |
| name: Build image per-arch and push by digest (${{ matrix.platform }}) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: [linux/amd64, linux/arm64] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Extract version from tag | |
| id: ver | |
| run: | | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=tag | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push by digest (${{ matrix.platform }}) | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| build-args: | | |
| VERSION=${{ steps.ver.outputs.VERSION }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| outputs: type=image,push-by-digest=true,name-canonical=true,push=true | |
| cache-from: | | |
| type=gha | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ github.ref_name }} | |
| cache-to: | | |
| type=gha,mode=max | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max | |
| type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ github.ref_name }},mode=max | |
| provenance: false | |
| sbom: false | |
| - name: Export digest | |
| run: | | |
| mkdir -p "${{ runner.temp }}/digests" | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "${{ runner.temp }}/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digests-${{ matrix.platform }} | |
| path: ${{ runner.temp }}/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| docker_merge_manifest: | |
| name: Create and push multi-arch manifest | |
| runs-on: ubuntu-latest | |
| needs: docker_build_by_platform | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: docker/setup-buildx-action@v3 | |
| - id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=tag | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Download digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ${{ runner.temp }}/digests | |
| pattern: digests-* | |
| merge-multiple: true | |
| - name: Create manifest list and push | |
| working-directory: ${{ runner.temp }}/digests | |
| run: | | |
| docker buildx imagetools create \ | |
| $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "${DOCKER_METADATA_OUTPUT_JSON}") \ | |
| $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) | |
| - name: Inspect image | |
| run: docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} | |
| create_release: | |
| name: Create GitHub Release with artifacts | |
| needs: build_dist | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT | |
| echo "## Changes in ${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| git log --pretty=format:"- %s" $(git describe --tags --abbrev=0 HEAD^)..HEAD >> $GITHUB_OUTPUT || echo "- Initial release" >> $GITHUB_OUTPUT | |
| echo "" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: Release ${{ github.ref_name }} | |
| body: ${{ steps.changelog.outputs.CHANGELOG }} | |
| draft: false | |
| prerelease: false | |
| files: | | |
| dist/* | |
| generate_release_notes: true | |
| publish_mcp_registry: | |
| name: Publish to MCP Registry (preview) | |
| needs: [publish_pypi, docker_merge_manifest] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install MCP Publisher CLI | |
| run: | | |
| curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher | |
| - name: Extract version from tag | |
| id: ver | |
| run: | | |
| echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT | |
| - name: Generate server.json | |
| env: | |
| VERSION: ${{ steps.ver.outputs.VERSION }} | |
| run: | | |
| python - <<'PY' | |
| import json, tomllib, os | |
| VERSION = os.environ['VERSION'] | |
| with open('pyproject.toml','rb') as f: | |
| proj = tomllib.load(f)['project'] | |
| desc = (proj.get('description','') or '')[:100] # MCP Registry requires <= 100 chars | |
| data = { | |
| "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", | |
| "name": "io.github.OtherVibes/mcp-as-a-judge", | |
| "description": desc, | |
| "version": VERSION, | |
| "transports": [ | |
| "stdio" | |
| ], | |
| "packages": [ | |
| {"registry_type": "pypi", "identifier": "mcp-as-a-judge", "version": VERSION} | |
| ] | |
| } | |
| with open('server.json','w') as f: json.dump(data,f,indent=2) | |
| PY | |
| - name: Login to MCP Registry (GitHub OIDC) | |
| run: ./mcp-publisher login github-oidc | |
| - name: Publish to MCP Registry | |
| run: ./mcp-publisher publish | |
| - name: Verify publication | |
| env: | |
| NAME: io.github.othervibes/mcp-as-a-judge | |
| run: | | |
| for i in {1..10}; do | |
| sleep 3 | |
| curl -sf "https://registry.modelcontextprotocol.io/v0/servers?search=$NAME" -o out.json || true | |
| python - <<'PY' | |
| import json, sys, os | |
| name = os.environ['NAME'] | |
| try: | |
| data=json.load(open('out.json')) | |
| except Exception: | |
| sys.exit(1) | |
| items = [] | |
| if isinstance(data, dict): | |
| items = data.get('results') or data.get('servers') or data.get('data') or [] | |
| elif isinstance(data, list): | |
| items = data | |
| ok = any(isinstance(s, dict) and s.get('name') == name for s in items) | |
| sys.exit(0 if ok else 1) | |
| PY | |
| if [ $? -eq 0 ]; then echo "Verified $NAME in registry"; exit 0; fi | |
| done | |
| echo "Server not visible in registry yet" | |
| exit 1 |