Skip to content

add new CI guard to check if a changeset was included (#53) #71

add new CI guard to check if a changeset was included (#53)

add new CI guard to check if a changeset was included (#53) #71

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
# Cancel in-progress runs for the same ref when a new commit is pushed.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# A PR that changes npm-visible files must carry a changeset — without one
# the Release workflow versions nothing and silently ships no release
# (AGENTS.md "Releases"). Docs-site-only and CI-only PRs pass with no
# changeset. An intentional no-release change opts out with
# `npx changeset --empty`. Push builds on main skip the job: there is no
# PR diff to police there, and the changesets already merged.
changeset-guard:
name: Changeset guard
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Full history, so the merge base with the PR's target branch
# exists for the three-dot diff and `changeset status --since`.
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- name: Require a changeset for npm-visible changes
env:
BASE_REF: ${{ github.base_ref }}
# The path filter runs before `npm ci`, so docs/CI-only PRs pass in
# seconds without an install. `changeset status --since` then also
# parse-validates the changeset files (bad frontmatter or a wrong
# package name fails here instead of in the Release run on main).
run: |
base="origin/$BASE_REF"
changed=$(git diff --name-only "$base...HEAD")
echo "Changed files vs $base:"
echo "$changed"
npm_visible=$(echo "$changed" | grep -E '^(src/|package\.json$|package-lock\.json$|tsup\.config\.ts$|tsconfig\.json$)' || true)
if [ -z "$npm_visible" ]; then
echo "No npm-visible changes; no changeset required."
exit 0
fi
echo "npm-visible changes:"
echo "$npm_visible"
added_changesets=$(echo "$changed" | grep -E '^\.changeset/.+\.md$' | grep -vE 'README\.md$' || true)
if [ -z "$added_changesets" ]; then
echo "::error::This PR changes npm-visible files but contains no changeset. Run 'npx changeset' (or 'npx changeset --empty' for an intentional no-release change) and commit the generated file."
exit 1
fi
echo "Changeset(s) in this PR:"
echo "$added_changesets"
npm ci
npx changeset status --since="$base"
test:
name: Test (Node ${{ matrix.node }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: ['22', '24', 'latest']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
- name: Install dependencies
run: npm ci
- name: Typecheck
run: npm run typecheck
- name: Unit & integration tests
run: npm test
- name: Build
run: npm run build
- name: Verify dist exports
run: node scripts/test-dist.mjs
- name: Verify browser bundle
run: npm run test:browser-bundle
e2e:
name: Browser e2e (OAuth)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- name: Install dependencies
run: npm ci
- name: Install Playwright Chromium
run: npx playwright install --with-deps chromium
- name: Run browser e2e tests
run: npm run test:e2e
conformance-server:
name: MCP conformance (server)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- name: Install dependencies
run: npm ci
# Boots the everything-server fixture, runs the pinned
# @modelcontextprotocol/conformance suite (active + draft) against it, and
# applies conformance-baseline.yml. Fails the job (and the PR) on any
# regression or stale baseline entry — see tests/conformance/run-server.mjs.
- name: Run server conformance suite
run: npm run conformance:server
conformance-client:
name: MCP conformance (client)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- name: Install dependencies
run: npm ci
# Runs the pinned @modelcontextprotocol/conformance suite in client mode
# against the everything-client fixture (the four non-auth core scenarios,
# plus the 14 [2025-11-25]-era core auth/* OAuth scenarios driven through
# the OAuth-configured client driver, plus the draft filter) and applies
# conformance-baseline.yml. Fails the job (and the PR) on any regression or
# stale baseline entry — see tests/conformance/run-client.mjs.
- name: Run client conformance suite
run: npm run conformance:client