From 038a2887d99eb4e089f55427b8c04dd194114545 Mon Sep 17 00:00:00 2001 From: Sanjith Sambath Date: Wed, 22 Jul 2026 11:29:06 -0700 Subject: [PATCH] ci: scope compatibility and marketplace checks --- .github/workflows/compatibility.yml | 64 +++++++++++++++++++++++++++++ .github/workflows/drift.yml | 11 +++++ .github/workflows/marketplace.yml | 57 +++++++++++++++++++++++++ .github/workflows/validate.yml | 47 --------------------- compatibility.json | 8 ---- scripts/check_compatibility.py | 21 +--------- 6 files changed, 134 insertions(+), 74 deletions(-) create mode 100644 .github/workflows/compatibility.yml create mode 100644 .github/workflows/marketplace.yml diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml new file mode 100644 index 0000000..10382a9 --- /dev/null +++ b/.github/workflows/compatibility.yml @@ -0,0 +1,64 @@ +name: Validate package compatibility + +on: + pull_request: + paths: + - compatibility.json + - tests/** + - .github/workflows/compatibility.yml + push: + branches: [main] + paths: + - compatibility.json + - tests/** + - .github/workflows/compatibility.yml + workflow_dispatch: + +permissions: + contents: read + +jobs: + compatibility: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Validate Python SDK signatures + run: | + version="$(python3 -c 'import json; print(json.load(open("compatibility.json"))["agentmail"]["python"])')" + python3 -m pip install "agentmail==$version" + python3 tests/test_sdk_signatures.py + + - name: Run Python webhook verification fixtures + run: | + python3 -m pip install svix + python3 tests/test_webhook_verification.py + + - name: Type-check TypeScript compatibility fixtures + run: | + sdk="$(node -p "require('./compatibility.json').agentmail.typescript")" + toolkit="$(node -p "require('./compatibility.json').toolkit.typescript")" + tmp="$(mktemp -d)" + cp tests/sdk_typescript.ts tests/webhook_typescript.ts tests/webhook_verification.ts tests/package.json "$tmp/" + cd "$tmp" + npm install --no-save "agentmail@$sdk" "agentmail-toolkit@$toolkit" "ai@6" "langchain@1" "svix" "express" "@types/express" "typescript@5.9.3" "tsx" "@types/node@22" + ./node_modules/.bin/tsc --noEmit --strict --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext sdk_typescript.ts webhook_typescript.ts webhook_verification.ts + ./node_modules/.bin/tsx webhook_verification.ts + + - name: Validate CLI command names + run: | + version="$(node -p "require('./compatibility.json').cli")" + npx -y "agentmail-cli@$version" inboxes --help | tee /tmp/inboxes-help + npx -y "agentmail-cli@$version" inboxes:messages --help | tee /tmp/messages-help + grep -q "get" /tmp/inboxes-help + grep -q "get" /tmp/messages-help + ! grep -q "retrieve" /tmp/inboxes-help + ! grep -q "retrieve" /tmp/messages-help diff --git a/.github/workflows/drift.yml b/.github/workflows/drift.yml index 72b4e71..9c567d1 100644 --- a/.github/workflows/drift.yml +++ b/.github/workflows/drift.yml @@ -1,6 +1,17 @@ name: Check upstream drift on: + pull_request: + paths: + - compatibility.json + - scripts/check_compatibility.py + - .github/workflows/drift.yml + push: + branches: [main] + paths: + - compatibility.json + - scripts/check_compatibility.py + - .github/workflows/drift.yml schedule: - cron: "17 16 * * 1" workflow_dispatch: diff --git a/.github/workflows/marketplace.yml b/.github/workflows/marketplace.yml new file mode 100644 index 0000000..ab4935d --- /dev/null +++ b/.github/workflows/marketplace.yml @@ -0,0 +1,57 @@ +name: Validate marketplaces + +on: + pull_request: + paths: + - .agents/** + - .claude-plugin/** + - .codex-plugin/** + - .cursor-plugin/** + - .plugin/** + - .mcp.json + - assets/** + - skills/** + - .github/workflows/marketplace.yml + push: + branches: [main] + paths: + - .agents/** + - .claude-plugin/** + - .codex-plugin/** + - .cursor-plugin/** + - .plugin/** + - .mcp.json + - assets/** + - skills/** + - .github/workflows/marketplace.yml + schedule: + - cron: "37 16 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + marketplace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Validate Codex marketplace installation + run: | + npm install --global @openai/codex + codex_home="$(mktemp -d)" + CODEX_HOME="$codex_home" codex plugin marketplace add . --json + CODEX_HOME="$codex_home" codex plugin list --available --json | tee /tmp/codex-plugins.json + grep -q '"pluginId": "agentmail@agentmail"' /tmp/codex-plugins.json + CODEX_HOME="$codex_home" codex plugin add agentmail@agentmail --json + + - name: Validate Claude plugin + run: | + npm install --global @anthropic-ai/claude-code + claude plugin validate . --strict + claude plugin validate .claude-plugin/plugin.json --strict diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 4e39098..e23facc 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -19,52 +19,5 @@ jobs: with: python-version: "3.12" - - uses: actions/setup-node@v4 - with: - node-version: "22" - - name: Validate repository structure run: python3 scripts/validate_repo.py - - - name: Validate Python SDK signatures - run: | - python3 -m pip install "agentmail==0.5.8" - python3 tests/test_sdk_signatures.py - - - name: Run Python webhook verification fixtures - run: | - python3 -m pip install svix - python3 tests/test_webhook_verification.py - - - name: Type-check and run TypeScript SDK examples - run: | - tmp="$(mktemp -d)" - cp tests/sdk_typescript.ts tests/webhook_typescript.ts tests/webhook_verification.ts tests/package.json "$tmp/" - cd "$tmp" - npm install --no-save "agentmail@0.5.17" "agentmail-toolkit@0.5.1" "ai@6" "langchain@1" "svix" "express" "@types/express" "typescript@5.9.3" "tsx" "@types/node@22" - ./node_modules/.bin/tsc --noEmit --strict --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext sdk_typescript.ts webhook_typescript.ts webhook_verification.ts - ./node_modules/.bin/tsx webhook_verification.ts - - - name: Validate CLI command names - run: | - npx -y agentmail-cli@0.7.14 inboxes --help | tee /tmp/inboxes-help - npx -y agentmail-cli@0.7.14 inboxes:messages --help | tee /tmp/messages-help - grep -q "get" /tmp/inboxes-help - grep -q "get" /tmp/messages-help - ! grep -q "retrieve" /tmp/inboxes-help - ! grep -q "retrieve" /tmp/messages-help - - - name: Validate Codex marketplace installation - run: | - npm install --global @openai/codex - codex_home="$(mktemp -d)" - CODEX_HOME="$codex_home" codex plugin marketplace add . --json - CODEX_HOME="$codex_home" codex plugin list --available --json | tee /tmp/codex-plugins.json - grep -q '"pluginId": "agentmail@agentmail"' /tmp/codex-plugins.json - CODEX_HOME="$codex_home" codex plugin add agentmail@agentmail --json - - - name: Validate Claude plugin - run: | - npm install --global @anthropic-ai/claude-code - claude plugin validate . --strict - claude plugin validate .claude-plugin/plugin.json --strict diff --git a/compatibility.json b/compatibility.json index 81e17ef..c4dec2c 100644 --- a/compatibility.json +++ b/compatibility.json @@ -8,13 +8,5 @@ "toolkit": { "typescript": "0.5.1", "python": "0.3.0" - }, - "hostedMcp": { - "url": "https://mcp.agentmail.to/mcp", - "source": "https://github.com/agentmail-to/agentmail-mcp" - }, - "specifications": { - "openapi": "https://docs.agentmail.to/openapi.json", - "asyncapi": "https://docs.agentmail.to/asyncapi.json" } } diff --git a/scripts/check_compatibility.py b/scripts/check_compatibility.py index 60d60d0..332f037 100644 --- a/scripts/check_compatibility.py +++ b/scripts/check_compatibility.py @@ -1,11 +1,10 @@ #!/usr/bin/env python3 -"""Fail when verified AgentMail dependencies or public specs have drifted.""" +"""Fail when verified AgentMail package versions have drifted.""" from __future__ import annotations import json import sys -import urllib.error import urllib.request from pathlib import Path @@ -42,22 +41,6 @@ def fetch_json(url: str) -> dict: if version != expected[name] ] -openapi = fetch_json(EXPECTED["specifications"]["openapi"]) -asyncapi = fetch_json(EXPECTED["specifications"]["asyncapi"]) -if not str(openapi.get("openapi", "")).startswith("3."): - errors.append("AgentMail OpenAPI document is missing an OpenAPI 3.x marker") -if not str(asyncapi.get("asyncapi", "")).startswith("2."): - errors.append("AgentMail AsyncAPI document is missing an AsyncAPI 2.x marker") - -try: - request = urllib.request.Request(EXPECTED["hostedMcp"]["url"], headers=HEADERS) - urllib.request.urlopen(request, timeout=20).close() -except urllib.error.HTTPError as exc: - if exc.code not in {401, 405}: - errors.append(f"hosted MCP probe returned unexpected HTTP {exc.code}") -except urllib.error.URLError as exc: - errors.append(f"hosted MCP probe failed: {exc}") - if errors: print("Compatibility drift detected:", file=sys.stderr) for item in errors: @@ -66,4 +49,4 @@ def fetch_json(url: str) -> dict: for name in sorted(actual): print(f"{name}: {actual[name]}") -print("AgentMail OpenAPI, AsyncAPI, and hosted MCP probes passed") +print("AgentMail package versions match compatibility.json")