v1.5.1 #34
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: Publish to PyPI and npm | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| publish_pypi: | |
| description: 'Publish to PyPI' | |
| required: true | |
| default: true | |
| type: boolean | |
| publish_npm: | |
| description: 'Publish to npm' | |
| required: true | |
| default: true | |
| type: boolean | |
| permissions: | |
| contents: read | |
| id-token: write # Required for PyPI trusted publishing | |
| jobs: | |
| test-mcp: | |
| name: Test MCP Server | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Test MCP server starts | |
| run: | | |
| timeout 10 python pomera_mcp_server.py --list-tools || true | |
| echo "MCP server tool listing completed" | |
| - name: Verify mcp.json exists | |
| run: | | |
| if [ ! -f "mcp.json" ]; then | |
| echo "ERROR: mcp.json manifest is missing!" | |
| exit 1 | |
| fi | |
| echo "✅ mcp.json manifest found" | |
| cat mcp.json | |
| - name: Verify llms.txt exists | |
| run: | | |
| if [ ! -f "llms.txt" ]; then | |
| echo "⚠️ WARNING: llms.txt is missing (recommended for AI discoverability)" | |
| else | |
| echo "✅ llms.txt found" | |
| fi | |
| build-pypi: | |
| name: Build PyPI Package | |
| runs-on: ubuntu-latest | |
| needs: test-mcp | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Get version from release tag | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" == "release" ]; then | |
| # Strip 'v' prefix from tag (v1.0.0 -> 1.0.0) | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "📦 Building version: $VERSION" | |
| else | |
| # Use version from pyproject.toml for manual runs | |
| VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "📦 Building version: $VERSION (from pyproject.toml)" | |
| fi | |
| # Note: File modifications removed - they cause uncommitted changes | |
| # which make setuptools_scm generate .dev0 versions | |
| # - package.json is updated by bump_version.py before tagging | |
| # - pyproject.toml version is dynamic (uses setuptools_scm) | |
| # - mcp.json version is updated by publish-mcp-registry job | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine | |
| - name: Build package | |
| run: python -m build | |
| - name: Check package | |
| run: twine check dist/* | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pypi-dist | |
| path: dist/ | |
| - name: Upload version files | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: version-files | |
| path: | | |
| pyproject.toml | |
| package.json | |
| mcp.json | |
| publish-pypi: | |
| name: Publish to PyPI | |
| runs-on: ubuntu-latest | |
| needs: build-pypi | |
| if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_pypi) | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/pomera-ai-commander | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: pypi-dist | |
| path: dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| # Uses trusted publishing (OIDC) - no API token needed | |
| # Configure at: https://pypi.org/manage/project/pomera-ai-commander/settings/publishing/ | |
| skip-existing: true | |
| publish-npm: | |
| name: Publish to npm | |
| runs-on: ubuntu-latest | |
| needs: build-pypi # Wait for build to complete (includes version updates) | |
| if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_npm) | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download version files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: version-files | |
| path: . | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Verify package.json | |
| run: | | |
| if [ ! -f "package.json" ]; then | |
| echo "ERROR: package.json is missing!" | |
| exit 1 | |
| fi | |
| echo "✅ package.json found" | |
| echo "Version: $(jq -r '.version' package.json)" | |
| - name: Verify bin script exists | |
| run: | | |
| if [ ! -f "bin/pomera-ai-commander.js" ]; then | |
| echo "ERROR: bin/pomera-ai-commander.js is missing!" | |
| exit 1 | |
| fi | |
| echo "✅ bin script found" | |
| - name: Generate version file from tag | |
| run: | | |
| # Extract clean version from git tag (strip 'v' prefix) | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| echo "Generating pomera/_version.py for npm package: ${VERSION}" | |
| # Create properly formatted _version.py | |
| mkdir -p pomera | |
| cat > pomera/_version.py << EOF | |
| # AUTO-GENERATED by setuptools_scm - DO NOT EDIT | |
| __version__ = "${VERSION}" | |
| EOF | |
| # Verify the generated file | |
| echo "Generated pomera/_version.py:" | |
| cat pomera/_version.py | |
| # Set up Python to test import | |
| if command -v python3 > /dev/null 2>&1; then | |
| python3 -c "import sys; sys.path.insert(0, '.'); from pomera._version import __version__; print(f'✅ Version verified: {__version__}')" | |
| else | |
| echo "✅ Version file created (Python verification skipped)" | |
| fi | |
| - name: Publish to npm | |
| run: npm publish --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| verify-publication: | |
| name: Verify Publications | |
| runs-on: ubuntu-latest | |
| needs: [publish-pypi, publish-npm] | |
| if: always() && (needs.publish-pypi.result == 'success' || needs.publish-npm.result == 'success') | |
| steps: | |
| - name: Wait for package availability | |
| run: sleep 60 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Verify PyPI installation | |
| if: needs.publish-pypi.result == 'success' | |
| run: | | |
| pip install pomera-ai-commander --upgrade | |
| python -c "import pomera_mcp_server; print('✅ PyPI package works!')" | |
| - name: Verify npm installation | |
| if: needs.publish-npm.result == 'success' | |
| run: | | |
| npm install -g pomera-ai-commander | |
| echo "✅ npm package installed successfully!" | |
| publish-mcp-registry: | |
| name: Publish to MCP Registry | |
| runs-on: ubuntu-latest | |
| needs: [publish-pypi, publish-npm] | |
| if: github.event_name == 'release' | |
| permissions: | |
| id-token: write # Required for OIDC authentication | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download version files | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: version-files | |
| path: . | |
| - name: Update server.json version | |
| run: | | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| # Update both the server version and package versions | |
| jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v | .packages[1].version = $v' server.json > server.json.tmp && mv server.json.tmp server.json | |
| echo "Updated server.json to version $VERSION" | |
| cat server.json | |
| - name: Install mcp-publisher | |
| run: | | |
| curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(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: Authenticate to MCP Registry | |
| run: ./mcp-publisher login github-oidc | |
| - name: Wait for PyPI package availability | |
| run: | | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| echo "Waiting for PyPI to propagate version $VERSION..." | |
| # Retry up to 10 times with 30 second delays (5 minutes total) | |
| for i in {1..10}; do | |
| HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/pomera-ai-commander/$VERSION/json") | |
| if [ "$HTTP_CODE" = "200" ]; then | |
| echo "✓ PyPI package $VERSION is available!" | |
| exit 0 | |
| fi | |
| echo "Attempt $i/10: PyPI returned $HTTP_CODE, waiting 30 seconds..." | |
| sleep 30 | |
| done | |
| echo "✗ PyPI package not available after 5 minutes" | |
| exit 1 | |
| - name: Publish server to MCP Registry | |
| run: ./mcp-publisher publish | |