Skip to content

Release mcp v0.11.0 #94

Release mcp v0.11.0

Release mcp v0.11.0 #94

Workflow file for this run

name: Validate
on:
push:
branches: [main, "runapi-ci/**"]
tags: ["v*", "*/v*"]
pull_request:
branches: [main]
permissions:
contents: read
defaults:
run:
shell: bash
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
package:
name: Package lifecycle
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # zizmor: ignore[cache-poisoning] cache is opt-in and no cache input is configured; v4
with:
node-version: 22
- name: Install dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Typecheck
run: npm run typecheck
- name: Build
run: npm run build
- name: Test
run: npm test
- name: Verify server identity
run: |
node --input-type=module <<'NODE'
import fs from "node:fs";
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
const server = JSON.parse(fs.readFileSync("server.json", "utf8"));
const expectedName = "io.github.runapi-builder/runapi-mcp";
const declared = server.packages?.[0];
if (server.name !== expectedName || pkg.mcpName !== expectedName) throw new Error("server name drift");
if (server.version !== pkg.version || declared?.version !== pkg.version) throw new Error("server version drift");
if (declared?.identifier !== pkg.name || declared?.transport?.type !== "stdio") throw new Error("server package drift");
NODE
- name: Stdio smoke
run: npm test -- tests/integration/stdio-server.test.ts
- name: Verify package boundary
run: |
npm pack --dry-run --json --ignore-scripts > "$RUNNER_TEMP/npm-pack.json"
node --input-type=module <<'NODE'
import fs from "node:fs";
const report = JSON.parse(fs.readFileSync(process.env.RUNNER_TEMP + "/npm-pack.json", "utf8"));
const files = report[0].files.map((entry) => entry.path);
const required = ["package.json","README.md","README.zh-CN.md","CHANGELOG.md","LICENSE","data/contract.json","glama.json"];
const requiredPrefixes = ["dist/","dist/bin/"];
const missing = required.filter((path) => !files.includes(path));
const missingPrefixes = requiredPrefixes.filter((prefix) => !files.some((path) => path.startsWith(prefix)));
const forbidden = files.filter((path) => ["src/", "tests/", "scripts/", ".github/"].some((prefix) => path.startsWith(prefix)));
if (missing.length || missingPrefixes.length || forbidden.length) {
throw new Error(JSON.stringify({ missing, missingPrefixes, forbidden }));
}
NODE