diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90056ba9..f6bd8d32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,4 +27,6 @@ jobs: - run: npm run build:all + - run: npm test + - run: npm run prettier diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 00000000..101e40c3 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -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 }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e69de29b..8ec033bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 � Secrets and variables � 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 � Environments � 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. diff --git a/package-lock.json b/package-lock.json index f7e65ac0..de750557 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index c73a58c1..4fd3596c 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,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", @@ -49,6 +50,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", @@ -63,7 +65,6 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "^1.23.0", - "bun": "^1.3.2", "react": "^19.2.0", "react-dom": "^19.2.0", "zod": "^3.25"