Repository navigation
DX-3022: Add @upstash/mcp-toolkit: long-running MCP tools (tasks) and… #304
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| # Nightly run on main so we notice breakage from upstream changes (Redis, model | |
| # providers, unpinned deps) even on days without commits. | |
| schedule: | |
| - cron: "0 0 * * *" | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| name: lint · typecheck · test · build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@v4 | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| # pnpm 11 (pinned via packageManager) requires Node >=22.13; use 24 LTS. | |
| node-version: 24 | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Lint (eslint + prettier) | |
| run: pnpm lint | |
| - name: Typecheck | |
| run: pnpm typecheck | |
| # Read-only: the telemetry VERSION constants are written by `pnpm ci:version` at release time, | |
| # so this only fails if a version was bumped without it. | |
| - name: Check version constants | |
| run: node scripts/sync-version.mjs --check | |
| - name: Build packages | |
| run: pnpm build | |
| - name: Test | |
| # Tests run against a real Upstash Redis. Add UPSTASH_REDIS_REST_URL / | |
| # UPSTASH_REDIS_REST_TOKEN as repo secrets to enable them; without secrets the | |
| # Redis-backed suites skip themselves and CI stays green. | |
| run: pnpm test | |
| env: | |
| UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }} | |
| UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }} | |
| UPSTASH_BLOB_TOKEN: ${{ secrets.UPSTASH_BLOB_TOKEN }} | |
| - name: Build example apps | |
| run: pnpm -r --filter "./examples/*" build | |
| - name: E2E (TanStack AI demo, two instances, mocked model) | |
| # Starts two production servers of examples/tanstack-ai-demo against the same Upstash Redis, | |
| # with a scripted model (no provider key), and checks what only shared backends can do: | |
| # resume a dropped stream on the other instance, rebuild a thread mid-run there, recall | |
| # memory across threads and instances, and produce a doubly-POSTed run exactly once. | |
| # Uses the app built by the step above; skipped without Redis secrets (e.g. fork PRs). | |
| working-directory: examples/tanstack-ai-demo | |
| env: | |
| UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }} | |
| UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }} | |
| run: | | |
| if [ -z "$UPSTASH_REDIS_REST_URL" ]; then | |
| echo "No Redis secrets available — skipping the TanStack AI e2e suite." | |
| exit 0 | |
| fi | |
| pnpm e2e | |
| - name: E2E (MCP toolkit demo, local QStash, no model) | |
| # Starts the local QStash dev server and the demo built above, and drives it with raw JSON-RPC | |
| # as a model and a host would (no model, no QStash account). Against both task servers: run to | |
| # completion, cancel, another user's task reads as unknown, a throwing task ends `failed`, | |
| # unsigned or forged deliveries are refused. Against Deploy Watch: filtered webhooks with | |
| # valid signatures, per-user subscriptions, `authorize` checked at delivery, 410 deletes the | |
| # subscription. Skipped without Redis secrets (e.g. fork PRs). | |
| working-directory: examples/mcp-toolkit-demo | |
| env: | |
| UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }} | |
| UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }} | |
| run: | | |
| if [ -z "$UPSTASH_REDIS_REST_URL" ]; then | |
| echo "No Redis secrets available — skipping the MCP toolkit e2e suite." | |
| exit 0 | |
| fi | |
| pnpm e2e | |
| - name: E2E eval (eve memory slots, mocked model) | |
| # Boots the eve demo's agent with a scripted mockModel (no model provider, no | |
| # OPENAI_API_KEY) and asserts both Upstash Redis memory integrations run at eve's real | |
| # memory lifecycle boundaries against real Redis: redisMemory() captures a turn and recalls | |
| # it, and fileMemory({ backend: redisDocuments() }) saves and recalls its document. | |
| working-directory: examples/eve-demo | |
| env: | |
| UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }} | |
| UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }} | |
| AGENTKIT_MOCK_MODEL: "1" | |
| run: | | |
| if [ -z "$UPSTASH_REDIS_REST_URL" ]; then | |
| echo "No Redis secrets available — skipping the e2e eval." | |
| exit 0 | |
| fi | |
| npx eve eval | |
| - name: E2E eval (eve extension, mocked model) | |
| # Boots the extension demo's agent with a scripted mockModel (no model provider, | |
| # no OPENAI_API_KEY) and asserts the extension's tools execute against real Redis | |
| # end to end. Reuses the same Redis secrets as the tests; skipped when they are | |
| # absent (e.g. fork PRs, which don't receive secrets). | |
| working-directory: examples/eve-extension-demo | |
| env: | |
| UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }} | |
| UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }} | |
| AGENTKIT_MOCK_MODEL: "1" | |
| run: | | |
| if [ -z "$UPSTASH_REDIS_REST_URL" ]; then | |
| echo "No Redis secrets available — skipping the e2e eval." | |
| exit 0 | |
| fi | |
| npx eve eval |