Repository navigation
Merge pull request #151 from Sendmux/codex/harden-sdk-tooling #212
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 Please | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| inputs: | |
| recover_ts_cli_version: | |
| description: Existing ts-cli release version to publish and attach assets for; leave empty for no-op. | |
| required: false | |
| type: string | |
| recover_mcp_registry_version: | |
| description: Existing sendmux-mcp version to publish to the MCP Registry; leave empty for no-op. | |
| required: false | |
| type: string | |
| permissions: {} | |
| concurrency: | |
| group: release-please-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| release-please: | |
| if: ${{ github.event_name == 'push' }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| outputs: | |
| releases_created: ${{ steps.release.outputs.releases_created }} | |
| paths_released: ${{ steps.release.outputs.paths_released }} | |
| rust_release_created: ${{ steps.release.outputs['rust--release_created'] }} | |
| steps: | |
| - name: Run release-please | |
| id: release | |
| uses: googleapis/release-please-action@0dfd8538845b8e92600d271a895a5372865d4062 # v5 | |
| with: | |
| config-file: release-please-config.json | |
| manifest-file: .release-please-manifest.json | |
| publish-npm: | |
| needs: release-please | |
| if: >- | |
| ${{ | |
| needs.release-please.outputs.releases_created == 'true' && | |
| ( | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/core') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/sending') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/mailbox') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/management') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/sdk') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/ai-sdk') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ts/cli') | |
| ) | |
| }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Check out OpenAPI snapshots | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| repository: Sendmux/docs | |
| path: sendmux-docs | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 | |
| with: | |
| version: 10.22.0 | |
| - name: Set up Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: 22 | |
| registry-url: https://registry.npmjs.org | |
| package-manager-cache: false | |
| - name: Set up Go | |
| uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 | |
| with: | |
| go-version: "1.23.x" | |
| cache-dependency-path: go/go.sum | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 | |
| with: | |
| ruby-version: "3.4.1" | |
| bundler-cache: false | |
| - name: Set up npm for trusted publishing | |
| run: npm install --global npm@11.5.1 | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build and verify | |
| run: pnpm build | |
| - name: Publish TypeScript packages to npm | |
| run: pnpm publish:npm:ts | |
| - name: Pack CLI tarballs | |
| if: ${{ contains(needs.release-please.outputs.paths_released, 'packages/ts/cli') }} | |
| run: pnpm --filter @sendmux/cli pack:tarballs | |
| - name: Verify CLI tarballs | |
| if: ${{ contains(needs.release-please.outputs.paths_released, 'packages/ts/cli') }} | |
| run: pnpm check:cli-tarballs | |
| - name: Attach CLI tarballs to GitHub Release | |
| if: ${{ contains(needs.release-please.outputs.paths_released, 'packages/ts/cli') }} | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| tag="ts-cli-v$(node -p "require('./packages/ts/cli/package.json').version")" | |
| mapfile -t assets < <(find packages/ts/cli/dist -type f \( -name "*.tar.gz" -o -name "*.tar.xz" -o -name "*.sha256" \) -print) | |
| if [ "${#assets[@]}" -eq 0 ]; then | |
| echo "No CLI tarballs found under packages/ts/cli/dist" >&2 | |
| exit 1 | |
| fi | |
| gh release upload "$tag" "${assets[@]}" --clobber | |
| - name: Update Homebrew tap | |
| if: ${{ contains(needs.release-please.outputs.paths_released, 'packages/ts/cli') }} | |
| env: | |
| GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| SENDMUX_HOMEBREW_TAP_REPO: Sendmux/homebrew-tap | |
| run: node scripts/update-homebrew-tap.mjs | |
| publish-cratesio: | |
| needs: release-please | |
| if: ${{ needs.release-please.outputs.rust_release_created == 'true' }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: read | |
| id-token: write | |
| defaults: | |
| run: | |
| working-directory: rust | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Rust | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup default stable | |
| - name: Verify crates.io package | |
| run: cargo publish --dry-run --locked | |
| - name: Authenticate to crates.io | |
| id: auth | |
| uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 | |
| - name: Publish Rust crate to crates.io | |
| run: cargo publish --locked | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} | |
| recover-ts-cli-release: | |
| if: ${{ github.event_name == 'workflow_dispatch' && inputs.recover_ts_cli_version != '' }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Check out OpenAPI snapshots | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| repository: Sendmux/docs | |
| path: sendmux-docs | |
| - name: Verify CLI recovery target | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RECOVER_TS_CLI_VERSION: ${{ inputs.recover_ts_cli_version }} | |
| run: | | |
| set -euo pipefail | |
| package_version="$(node -p "require('./packages/ts/cli/package.json').version")" | |
| if [ "$RECOVER_TS_CLI_VERSION" != "$package_version" ]; then | |
| echo "Recovery version $RECOVER_TS_CLI_VERSION does not match @sendmux/cli package version $package_version" >&2 | |
| exit 1 | |
| fi | |
| gh release view "ts-cli-v${RECOVER_TS_CLI_VERSION}" --json tagName --jq .tagName | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 | |
| with: | |
| version: 10.22.0 | |
| - name: Set up Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: 22 | |
| registry-url: https://registry.npmjs.org | |
| package-manager-cache: false | |
| - name: Set up Go | |
| uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 | |
| with: | |
| go-version: "1.23.x" | |
| cache-dependency-path: go/go.sum | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 | |
| with: | |
| ruby-version: "3.4.1" | |
| bundler-cache: false | |
| - name: Set up npm for trusted publishing | |
| run: npm install --global npm@11.5.1 | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build and verify | |
| run: pnpm build | |
| - name: Publish CLI package to npm | |
| run: pnpm publish:npm:ts | |
| env: | |
| SENDMUX_NPM_PUBLISH_PACKAGES: packages/ts/cli | |
| - name: Pack CLI tarballs | |
| run: pnpm --filter @sendmux/cli pack:tarballs | |
| - name: Verify CLI tarballs | |
| run: pnpm check:cli-tarballs | |
| - name: Attach CLI tarballs to GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RECOVER_TS_CLI_VERSION: ${{ inputs.recover_ts_cli_version }} | |
| run: | | |
| set -euo pipefail | |
| tag="ts-cli-v${RECOVER_TS_CLI_VERSION}" | |
| mapfile -t assets < <(find packages/ts/cli/dist -type f \( -name "*.tar.gz" -o -name "*.tar.xz" -o -name "*.sha256" \) -print) | |
| if [ "${#assets[@]}" -eq 0 ]; then | |
| echo "No CLI tarballs found under packages/ts/cli/dist" >&2 | |
| exit 1 | |
| fi | |
| gh release upload "$tag" "${assets[@]}" --clobber | |
| - name: Update Homebrew tap | |
| env: | |
| GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| SENDMUX_HOMEBREW_TAP_REPO: Sendmux/homebrew-tap | |
| run: node scripts/update-homebrew-tap.mjs | |
| recover-mcp-registry-release: | |
| if: ${{ github.event_name == 'workflow_dispatch' && inputs.recover_mcp_registry_version != '' }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Prepare MCP Registry recovery manifest | |
| id: mcp-manifest | |
| env: | |
| RECOVER_MCP_REGISTRY_VERSION: ${{ inputs.recover_mcp_registry_version }} | |
| run: | | |
| set -euo pipefail | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| import tomllib | |
| from pathlib import Path | |
| root = Path.cwd() | |
| pyproject = tomllib.loads((root / "packages/python/mcp/pyproject.toml").read_text()) | |
| version = pyproject["project"]["version"] | |
| requested_version = os.environ["RECOVER_MCP_REGISTRY_VERSION"] | |
| if requested_version != version: | |
| raise SystemExit(f"Recovery version {requested_version} does not match sendmux-mcp package version {version}") | |
| server_path = root / "packages/python/mcp/server.json" | |
| server = json.loads(server_path.read_text()) | |
| if server["name"] != "io.github.Sendmux/sendmux-mcp": | |
| raise SystemExit(f"Unexpected MCP Registry name: {server['name']}") | |
| marker = (root / "packages/python/mcp/README.md").read_text() | |
| expected_marker = f"mcp-name: {server['name']}" | |
| if expected_marker not in marker: | |
| raise SystemExit(f"Missing README marker: {expected_marker}") | |
| server["version"] = version | |
| for package in server.get("packages", []): | |
| if package.get("registryType") == "pypi" and package.get("identifier") == "sendmux-mcp": | |
| package["version"] = version | |
| break | |
| else: | |
| raise SystemExit("Missing PyPI package entry for sendmux-mcp") | |
| server_path.write_text(json.dumps(server, indent=2) + "\n") | |
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: | |
| output.write(f"name={server['name']}\n") | |
| output.write(f"version={version}\n") | |
| print(f"Prepared {server['name']} {version}") | |
| PY | |
| - name: Verify released package marker | |
| env: | |
| MCP_SERVER_NAME: ${{ steps.mcp-manifest.outputs.name }} | |
| MCP_PACKAGE_VERSION: ${{ steps.mcp-manifest.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| curl -fsSL "https://pypi.org/pypi/sendmux-mcp/${MCP_PACKAGE_VERSION}/json" -o /tmp/sendmux-mcp.json | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| data = json.loads(Path("/tmp/sendmux-mcp.json").read_text()) | |
| description = data["info"].get("description") or "" | |
| expected_marker = f"mcp-name: {os.environ['MCP_SERVER_NAME']}" | |
| if data["info"]["version"] != os.environ["MCP_PACKAGE_VERSION"]: | |
| raise SystemExit("PyPI returned the wrong sendmux-mcp version") | |
| if expected_marker not in description: | |
| raise SystemExit(f"PyPI description missing marker: {expected_marker}") | |
| PY | |
| - name: Install MCP Registry publisher | |
| run: | | |
| set -euo pipefail | |
| 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 | |
| ./mcp-publisher --help | |
| - name: Validate MCP Registry manifest | |
| run: ./mcp-publisher validate packages/python/mcp/server.json | |
| - name: Check existing MCP Registry version | |
| id: mcp-registry-status | |
| env: | |
| MCP_SERVER_NAME: ${{ steps.mcp-manifest.outputs.name }} | |
| MCP_SERVER_VERSION: ${{ steps.mcp-manifest.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| already_published="$(node scripts/mcp-registry-version.mjs --check)" | |
| echo "already_published=${already_published}" >> "$GITHUB_OUTPUT" | |
| - name: Authenticate to MCP Registry | |
| if: ${{ steps.mcp-registry-status.outputs.already_published != 'true' }} | |
| run: ./mcp-publisher login github-oidc | |
| - name: Publish MCP Registry metadata | |
| if: ${{ steps.mcp-registry-status.outputs.already_published != 'true' }} | |
| run: ./mcp-publisher publish packages/python/mcp/server.json | |
| - name: Verify MCP Registry metadata | |
| env: | |
| MCP_SERVER_NAME: ${{ steps.mcp-manifest.outputs.name }} | |
| MCP_SERVER_VERSION: ${{ steps.mcp-manifest.outputs.version }} | |
| run: node scripts/mcp-registry-version.mjs | |
| publish-pypi: | |
| needs: release-please | |
| if: >- | |
| ${{ | |
| ( | |
| needs.release-please.outputs.releases_created == 'true' && | |
| ( | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/core') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/sending') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/mailbox') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/management') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/sdk') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/mcp') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/python/langchain') | |
| ) | |
| ) | |
| }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Check out OpenAPI snapshots | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| repository: Sendmux/docs | |
| path: sendmux-docs | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 | |
| with: | |
| version: 10.22.0 | |
| - name: Set up Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: 22 | |
| package-manager-cache: false | |
| - name: Set up Python | |
| uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Set up Go | |
| uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 | |
| with: | |
| go-version: "1.23.x" | |
| cache-dependency-path: go/go.sum | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Python distributions | |
| env: | |
| PYTHON_PATHS_RELEASED: ${{ needs.release-please.outputs.paths_released }} | |
| run: pnpm build:python:dists | |
| - name: Select unpublished Python distributions | |
| id: python-publish | |
| run: pnpm prepare:publish:pypi | |
| - name: Publish Python packages to PyPI | |
| if: ${{ steps.python-publish.outputs.has_files == 'true' }} | |
| uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1 | |
| with: | |
| packages-dir: .tmp/python-publish | |
| publish-mcp-registry: | |
| needs: | |
| - release-please | |
| - publish-pypi | |
| if: >- | |
| ${{ | |
| needs.release-please.outputs.releases_created == 'true' && | |
| contains(fromJSON(needs.release-please.outputs.paths_released), 'packages/python/mcp') && | |
| needs.publish-pypi.result == 'success' | |
| }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Prepare MCP Registry manifest | |
| id: mcp-manifest | |
| run: | | |
| set -euo pipefail | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| import tomllib | |
| from pathlib import Path | |
| root = Path.cwd() | |
| pyproject = tomllib.loads((root / "packages/python/mcp/pyproject.toml").read_text()) | |
| version = pyproject["project"]["version"] | |
| server_path = root / "packages/python/mcp/server.json" | |
| server = json.loads(server_path.read_text()) | |
| if server["name"] != "io.github.Sendmux/sendmux-mcp": | |
| raise SystemExit(f"Unexpected MCP Registry name: {server['name']}") | |
| marker = (root / "packages/python/mcp/README.md").read_text() | |
| expected_marker = f"mcp-name: {server['name']}" | |
| if expected_marker not in marker: | |
| raise SystemExit(f"Missing README marker: {expected_marker}") | |
| server["version"] = version | |
| for package in server.get("packages", []): | |
| if package.get("registryType") == "pypi" and package.get("identifier") == "sendmux-mcp": | |
| package["version"] = version | |
| break | |
| else: | |
| raise SystemExit("Missing PyPI package entry for sendmux-mcp") | |
| server_path.write_text(json.dumps(server, indent=2) + "\n") | |
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: | |
| output.write(f"name={server['name']}\n") | |
| output.write(f"version={version}\n") | |
| print(f"Prepared {server['name']} {version}") | |
| PY | |
| - name: Wait for PyPI MCP package marker | |
| env: | |
| MCP_SERVER_NAME: ${{ steps.mcp-manifest.outputs.name }} | |
| MCP_PACKAGE_VERSION: ${{ steps.mcp-manifest.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| for attempt in {1..30}; do | |
| if curl -fsSL "https://pypi.org/pypi/sendmux-mcp/${MCP_PACKAGE_VERSION}/json" -o /tmp/sendmux-mcp.json; then | |
| if python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| data = json.loads(Path("/tmp/sendmux-mcp.json").read_text()) | |
| description = data["info"].get("description") or "" | |
| expected_marker = f"mcp-name: {os.environ['MCP_SERVER_NAME']}" | |
| if data["info"]["version"] != os.environ["MCP_PACKAGE_VERSION"]: | |
| raise SystemExit("PyPI returned the wrong sendmux-mcp version") | |
| if expected_marker not in description: | |
| raise SystemExit(f"PyPI description missing marker: {expected_marker}") | |
| PY | |
| then | |
| exit 0 | |
| fi | |
| fi | |
| sleep 10 | |
| done | |
| echo "Timed out waiting for PyPI sendmux-mcp ${MCP_PACKAGE_VERSION} marker" >&2 | |
| exit 1 | |
| - name: Install MCP Registry publisher | |
| run: | | |
| set -euo pipefail | |
| 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 | |
| ./mcp-publisher --help | |
| - name: Validate MCP Registry manifest | |
| run: ./mcp-publisher validate packages/python/mcp/server.json | |
| - name: Check existing MCP Registry version | |
| id: mcp-registry-status | |
| env: | |
| MCP_SERVER_NAME: ${{ steps.mcp-manifest.outputs.name }} | |
| MCP_SERVER_VERSION: ${{ steps.mcp-manifest.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| already_published="$(node scripts/mcp-registry-version.mjs --check)" | |
| echo "already_published=${already_published}" >> "$GITHUB_OUTPUT" | |
| - name: Authenticate to MCP Registry | |
| if: ${{ steps.mcp-registry-status.outputs.already_published != 'true' }} | |
| run: ./mcp-publisher login github-oidc | |
| - name: Publish MCP Registry metadata | |
| if: ${{ steps.mcp-registry-status.outputs.already_published != 'true' }} | |
| run: | | |
| set -euo pipefail | |
| attempts=12 | |
| for ((attempt = 1; attempt <= attempts; attempt++)); do | |
| if ./mcp-publisher publish packages/python/mcp/server.json 2>&1 | tee /tmp/mcp-publish.log; then | |
| exit 0 | |
| fi | |
| if ! node scripts/mcp-registry-version.mjs --retryable-publish-log /tmp/mcp-publish.log; then | |
| exit 1 | |
| fi | |
| if [ "${attempt}" -lt "${attempts}" ]; then | |
| sleep_seconds=$((attempt * 10)) | |
| echo "MCP Registry cannot see PyPI package yet; retrying in ${sleep_seconds}s." >&2 | |
| sleep "${sleep_seconds}" | |
| fi | |
| done | |
| echo "MCP Registry still cannot see PyPI package after ${attempts} attempts." >&2 | |
| exit 1 | |
| - name: Verify MCP Registry metadata | |
| env: | |
| MCP_SERVER_NAME: ${{ steps.mcp-manifest.outputs.name }} | |
| MCP_SERVER_VERSION: ${{ steps.mcp-manifest.outputs.version }} | |
| run: node scripts/mcp-registry-version.mjs | |
| publish-rubygems: | |
| needs: release-please | |
| if: >- | |
| ${{ | |
| needs.release-please.outputs.releases_created == 'true' && | |
| ( | |
| contains(needs.release-please.outputs.paths_released, 'packages/ruby/core') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ruby/sending') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ruby/mailbox') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ruby/management') || | |
| contains(needs.release-please.outputs.paths_released, 'packages/ruby/sdk') | |
| ) | |
| }} | |
| runs-on: ubuntu-latest | |
| environment: release | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Check out SDK | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Check out OpenAPI snapshots | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| repository: Sendmux/docs | |
| path: sendmux-docs | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8 | |
| with: | |
| version: 10.22.0 | |
| - name: Set up Node | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 | |
| with: | |
| node-version: 22 | |
| package-manager-cache: false | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 | |
| with: | |
| ruby-version: "3.4.1" | |
| bundler-cache: false | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Ruby gems | |
| run: pnpm build:ruby | |
| env: | |
| RUBY_PATHS_RELEASED: ${{ needs.release-please.outputs.paths_released }} | |
| - name: Configure RubyGems trusted publishing credentials | |
| uses: rubygems/configure-rubygems-credentials@762a4b77c3300434bb57c7ce80b20e36231927aa # v2.0.0 | |
| - name: Publish Ruby packages to RubyGems | |
| run: pnpm publish:rubygems | |
| env: | |
| RUBY_PATHS_RELEASED: ${{ needs.release-please.outputs.paths_released }} |