diff --git a/VERSION b/VERSION index 141f2e8..ace4423 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.15.0 +1.15.1 diff --git a/scaffold/create-tool.py b/scaffold/create-tool.py index 1b41d8b..6a6d300 100644 --- a/scaffold/create-tool.py +++ b/scaffold/create-tool.py @@ -178,10 +178,16 @@ def main(): if args.type == "cursor-plugin": write_file(output_dir, ".cursor-plugin/plugin.json", render_template(env, "plugin.json.j2", ctx)) - # GitHub workflows - write_file(output_dir, ".github/workflows/validate.yml", render_template(env, "validate.yml.j2", ctx)) - write_file(output_dir, ".github/workflows/release.yml", render_template(env, "release.yml.j2", ctx)) - write_file(output_dir, ".github/workflows/pages.yml", render_template(env, "pages.yml.j2", ctx)) + # GitHub workflows — branched by type + if args.type == "mcp-server": + write_file(output_dir, ".github/workflows/validate.yml", render_template(env, "validate.mcp.yml.j2", ctx)) + write_file(output_dir, ".github/workflows/release.yml", render_template(env, "release.mcp.yml.j2", ctx)) + write_file(output_dir, ".github/workflows/pages.yml", render_template(env, "pages.mcp.yml.j2", ctx)) + write_file(output_dir, ".github/workflows/publish.yml", render_template(env, "publish.yml.j2", ctx)) + else: + write_file(output_dir, ".github/workflows/validate.yml", render_template(env, "validate.yml.j2", ctx)) + write_file(output_dir, ".github/workflows/release.yml", render_template(env, "release.yml.j2", ctx)) + write_file(output_dir, ".github/workflows/pages.yml", render_template(env, "pages.yml.j2", ctx)) write_file(output_dir, ".github/workflows/stale.yml", render_template(env, "stale.yml.j2", ctx)) write_file(output_dir, ".github/workflows/drift-check.yml", render_template(env, "drift-check.yml.j2", ctx)) write_file(output_dir, ".github/workflows/label-sync.yml", render_template(env, "label-sync.yml.j2", ctx)) @@ -213,6 +219,11 @@ def main(): (output_dir / "assets" / ".gitkeep").touch() print(" created assets/.gitkeep") + # MCP server specific files + if args.type == "mcp-server": + write_file(output_dir, "package.json", render_template(env, "package.json.j2", ctx)) + write_file(output_dir, "docs/index.html", render_template(env, "docs/index.mcp.html.j2", ctx)) + # Skills for skill in skill_names: skill_content = f"""--- diff --git a/scaffold/templates/docs/index.mcp.html.j2 b/scaffold/templates/docs/index.mcp.html.j2 new file mode 100644 index 0000000..690b9f2 --- /dev/null +++ b/scaffold/templates/docs/index.mcp.html.j2 @@ -0,0 +1,19 @@ + + + + + + {{ name }} + + + +

{{ name }}

+

{{ description }}

+

Full documentation will be available here once the server implementation is complete.

+

View on GitHub

+ + diff --git a/scaffold/templates/package.json.j2 b/scaffold/templates/package.json.j2 new file mode 100644 index 0000000..c87c908 --- /dev/null +++ b/scaffold/templates/package.json.j2 @@ -0,0 +1,21 @@ +{ + "name": "@{{ repo_owner | lower }}/{{ slug }}", + "version": "0.1.0", + "description": "{{ description }}", + "type": "module", + "main": "dist/index.js", + "bin": {"{{ slug }}": "dist/index.js"}, + "files": ["dist", "README.md", "LICENSE"], + "scripts": { + "build": "echo 'No build target yet'", + "test": "echo 'No tests yet' && exit 0", + "prepublishOnly": "npm run build" + }, + "author": "{{ author_name }}", + "license": "{{ license_spdx }}", + "repository": {"type": "git", "url": "git+https://github.com/{{ repo_owner }}/{{ slug }}.git"}, + "homepage": "https://github.com/{{ repo_owner }}/{{ slug }}#readme", + "bugs": {"url": "https://github.com/{{ repo_owner }}/{{ slug }}/issues"}, + "keywords": ["mcp", "model-context-protocol", "developer-tools"], + "engines": {"node": ">=20.0.0"} +} diff --git a/scaffold/templates/pages.mcp.yml.j2 b/scaffold/templates/pages.mcp.yml.j2 new file mode 100644 index 0000000..0b123e0 --- /dev/null +++ b/scaffold/templates/pages.mcp.yml.j2 @@ -0,0 +1,37 @@ +name: Deploy GitHub Pages + +on: + push: + branches: [main] + paths: + - "docs/**" + - "assets/**" + workflow_dispatch: + +permissions: + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + deploy: +{% raw %} + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} +{% endraw %} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: actions/configure-pages@v6 + + - uses: actions/upload-pages-artifact@v5 + with: + path: docs + + - uses: actions/deploy-pages@v5 + id: deployment diff --git a/scaffold/templates/publish.yml.j2 b/scaffold/templates/publish.yml.j2 new file mode 100644 index 0000000..bbca65d --- /dev/null +++ b/scaffold/templates/publish.yml.j2 @@ -0,0 +1,29 @@ +name: Publish to npm + +on: + release: + types: [published] + +permissions: + contents: read + id-token: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 22 + registry-url: https://registry.npmjs.org + cache: npm + - run: npm install -g npm@latest + - run: npm ci + - run: npm run build + - run: npm test +{% raw %} + - run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} +{% endraw %} diff --git a/scaffold/templates/release.mcp.yml.j2 b/scaffold/templates/release.mcp.yml.j2 new file mode 100644 index 0000000..1e5f122 --- /dev/null +++ b/scaffold/templates/release.mcp.yml.j2 @@ -0,0 +1,72 @@ +name: Release + +on: + push: + branches: [main] + workflow_dispatch: {} + +permissions: + contents: write + +concurrency: + group: release + cancel-in-progress: false + +jobs: + tag-and-release: + name: Tag and release + runs-on: ubuntu-latest +{% raw %} + if: "!contains(github.event.head_commit.message, '[skip ci]')" + steps: + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Read version from package.json + id: ver + run: | + version=$(python3 -c "import json; print(json.load(open('package.json'))['version'])") + echo "version=$version" >> "$GITHUB_OUTPUT" + echo "Version from package.json: $version" + + - name: Check if tag already exists + id: check + run: | + version="${{ steps.ver.outputs.version }}" + if git rev-parse "v$version" >/dev/null 2>&1; then + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Tag v$version already exists, skipping release" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + echo "Tag v$version does not exist, proceeding" + fi + + - name: Create and push tags + if: steps.check.outputs.skip == 'false' + run: | + version="${{ steps.ver.outputs.version }}" + IFS='.' read -r major minor _patch <<< "$version" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git tag "v$version" + git tag -f "v$major" + git tag -f "v$major.$minor" + + git push origin "v$version" + git push origin "v$major" --force + git push origin "v$major.$minor" --force + + - name: Create GitHub Release + if: steps.check.outputs.skip == 'false' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "v${{ steps.ver.outputs.version }}" \ + --title "v${{ steps.ver.outputs.version }}" \ + --generate-notes +{% endraw %} diff --git a/scaffold/templates/validate.mcp.yml.j2 b/scaffold/templates/validate.mcp.yml.j2 new file mode 100644 index 0000000..f0804ec --- /dev/null +++ b/scaffold/templates/validate.mcp.yml.j2 @@ -0,0 +1,28 @@ +name: Validate + +on: + pull_request: + branches: [main] + push: + branches: [main] + +permissions: + contents: read + +jobs: + required-files: + name: Check required files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Verify required files exist + run: | + missing=0 + for f in README.md CHANGELOG.md AGENTS.md CLAUDE.md mcp-tools.json site.json LICENSE; do + if [ ! -f "$f" ]; then + echo "Missing: $f" + missing=1 + fi + done + if [ $missing -eq 1 ]; then exit 1; fi + echo "All required files present"