Add npm publish workflow (#89)

* Add npm publish workflow

- Add .github/workflows/npm-publish.yml triggered on GitHub releases
  - Runs build and test jobs before publishing
  - Uses NPM_TOKEN secret with OIDC provenance
  - Smart npm tagging: latest, beta, or release-X.Y
- Add prepack hook to package.json for automatic builds
- Move bun from dependencies to devDependencies
- Add npm test step to CI workflow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add CONTRIBUTING.md with maintainer publishing guide

- Getting started and development process for contributors
- Pull request guidelines
- Maintainer section with:
  - Repository setup (NPM_TOKEN, release environment)
  - Step-by-step release publishing instructions
  - npm tag documentation (latest, beta, release-X.Y)
  - Maintenance release workflow
  - Pre-release testing via pkg-pr-new

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ...

* Potential fix for code scanning alert no. 9: Workflow does not contain permissions

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
Olivier Chafik 2025-12-08 22:23:57 +01:00 • committed by GitHub
commit 2d842a31fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 242 additions and 2 deletions

View file

@ -27,4 +27,6 @@ jobs:
- run: npm run build:all
- run: npm test
- run: npm run prettier

85
.github/workflows/npm-publish.yml vendored Normal file
View file

@ -0,0 +1,85 @@
name: Publish to npm
on:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- run: npm ci
- run: npm run build
- run: npm run prettier
test:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- run: npm ci
- run: npm test
publish:
runs-on: ubuntu-latest
if: github.event_name == 'release'
environment: release
needs: [build, test]
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
registry-url: "https://registry.npmjs.org"
- run: npm ci
- name: Determine npm tag
id: npm-tag
run: |
VERSION=$(node -p "require('./package.json').version")
# Check if this is a beta release
if [[ "$VERSION" == *"-beta"* ]]; then
echo "tag=--tag beta" >> $GITHUB_OUTPUT
# Check if this release is from a non-main branch (patch/maintenance release)
elif [[ "${{ github.event.release.target_commitish }}" != "main" ]]; then
# Use "release-X.Y" as tag for old branch releases
MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1,2)
echo "tag=--tag release-${MAJOR_MINOR}" >> $GITHUB_OUTPUT
else
echo "tag=" >> $GITHUB_OUTPUT
fi
- run: npm publish --provenance --access public ${{ steps.npm-tag.outputs.tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View file

@ -0,0 +1,140 @@
# Contributing to MCP Apps SDK
We welcome contributions to the MCP Apps SDK! This document outlines the process for contributing to the project.
## Getting Started
1. Fork the repository
2. Clone your fork: `git clone https://github.com/YOUR-USERNAME/ext-apps.git`
3. Install dependencies: `npm install`
4. Build the project: `npm run build`
5. Run tests: `npm test`
## Development Process
1. Create a new branch for your changes
2. Make your changes
3. Run `npm run prettier` to ensure code style compliance
4. Run `npm test` to verify all tests pass
5. Submit a pull request
## Pull Request Guidelines
- Follow the existing code style
- Include tests for new functionality
- Update documentation as needed
- Keep changes focused and atomic
- Provide a clear description of changes
## Running Examples
Start the development environment with hot reloading:
```bash
npm run examples:dev
```
Or build and run examples:
```bash
npm run examples:start
```
## Code of Conduct
This project follows our [Code of Conduct](CODE_OF_CONDUCT.md). Please review it before contributing.
## Reporting Issues
- Use the [GitHub issue tracker](https://github.com/modelcontextprotocol/ext-apps/issues)
- Search existing issues before creating a new one
- Provide clear reproduction steps
## Security Issues
Please review our [Security Policy](SECURITY.md) for reporting security vulnerabilities.
---
## For Maintainers
### Repository Setup
Before publishing releases, ensure the following are configured:
1. **NPM_TOKEN secret**: Add an npm automation token to the repository secrets
- Go to Settings <20> Secrets and variables <20> Actions
- Create a new secret named `NPM_TOKEN`
- Value: an npm automation token with publish permissions for `@modelcontextprotocol/ext-apps`
2. **`release` environment** (optional): Create a protected environment for additional safeguards
- Go to Settings <20> Environments <20> New environment
- Name it `release`
- Add required reviewers or other protection rules as needed
### Publishing a Release
Releases are published automatically via GitHub Actions when a GitHub Release is created.
#### Steps to publish:
1. **Update the version** in `package.json`:
```bash
# For a regular release
npm version patch # or minor, or major
# For a beta release
npm version prerelease --preid=beta
```
2. **Commit the version bump** (if not done by `npm version`):
```bash
git add package.json
git commit -m "Bump version to X.Y.Z"
git push origin main
```
3. **Create a GitHub Release**:
- Go to [Releases](https://github.com/modelcontextprotocol/ext-apps/releases)
- Click "Draft a new release"
- Create a new tag matching the version (e.g., `v0.1.0`)
- Set the target branch (usually `main`)
- Write release notes describing the changes
- Click "Publish release"
4. **Monitor the workflow**:
- The [npm-publish workflow](https://github.com/modelcontextprotocol/ext-apps/actions/workflows/npm-publish.yml) will trigger automatically
- It runs build and test jobs before publishing
- On success, the package is published to npm with provenance
#### npm Tags
The workflow automatically determines the npm dist-tag:
| Version Pattern | npm Tag | Install Command |
| ----------------------------- | ------------- | -------------------------------------------------------- |
| `X.Y.Z` (from main) | `latest` | `npm install @modelcontextprotocol/ext-apps` |
| `X.Y.Z-beta.N` | `beta` | `npm install @modelcontextprotocol/ext-apps@beta` |
| `X.Y.Z` (from release branch) | `release-X.Y` | `npm install @modelcontextprotocol/ext-apps@release-X.Y` |
#### Maintenance Releases
To release a patch for an older version:
1. Create a release branch from the tag: `git checkout -b release-0.1 v0.1.0`
2. Cherry-pick or apply fixes
3. Bump the patch version
4. Create a GitHub Release targeting the release branch
5. The package will be published with tag `release-0.1`
### Testing Pre-releases
Every commit and PR automatically publishes a preview package via [pkg-pr-new](https://github.com/pkg-pr-new/pkg-pr-new). Check the PR comments or workflow logs for the install command.
---
## License
By contributing, you agree that your contributions will be licensed under the MIT License.

14
package-lock.json generated
View file

@ -12,7 +12,6 @@
],
"dependencies": {
"@modelcontextprotocol/sdk": "^1.23.0",
"bun": "^1.3.2",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"zod": "^3.25"
@ -21,6 +20,7 @@
"@types/bun": "^1.3.2",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"bun": "^1.3.2",
"concurrently": "^9.2.1",
"cors": "^2.8.5",
"esbuild": "^0.25.12",
@ -1084,6 +1084,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@ -1096,6 +1097,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@ -1108,6 +1110,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@ -1120,6 +1123,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -1132,6 +1136,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -1144,6 +1149,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -1156,6 +1162,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -1168,6 +1175,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -1180,6 +1188,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -1192,6 +1201,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@ -1204,6 +1214,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@ -2096,6 +2107,7 @@
"arm64",
"x64"
],
"dev": true,
"hasInstallScript": true,
"os": [
"darwin",

View file

@ -28,6 +28,7 @@
],
"scripts": {
"build": "bun build.bun.ts",
"prepack": "npm run build",
"build:all": "npm run build && npm run examples:build",
"test": "bun test",
"examples:build": "find examples -maxdepth 1 -mindepth 1 -type d -exec printf '%s\\0' 'npm run --workspace={} build' ';' | xargs -0 concurrently --kill-others-on-fail",
@ -55,6 +56,7 @@
"author": "Olivier Chafik",
"devDependencies": {
"@types/bun": "^1.3.2",
"bun": "^1.3.2",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"concurrently": "^9.2.1",
@ -69,7 +71,6 @@
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.23.0",
"bun": "^1.3.2",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"zod": "^3.25"