commit
5acef27cd7
|
|
@ -19,6 +19,14 @@ Save your change type
|
|||
<!-- If applicable, add screenshots or recordings to demonstrate the changes -->
|
||||
|
||||
|
||||
## Documentation Updates
|
||||
<!-- Check if you updated documentation for changes to tools/resources -->
|
||||
- [ ] I have added/removed/modified tools or resources
|
||||
- [ ] If yes, I have updated all documentation files using:
|
||||
- [ ] The LLM prompt at `tools/UPDATE_DOCS_PROMPT.md` (recommended)
|
||||
- [ ] Manual updates following the guide at `tools/UPDATE_DOCS.md`
|
||||
|
||||
|
||||
## Related Issues
|
||||
<!-- Link any related issues using "Fixes #123" or "Relates to #123" -->
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
name: Release
|
||||
|
||||
concurrency:
|
||||
group: release-main
|
||||
cancel-in-progress: false
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
|
|
@ -19,13 +23,25 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
outputs:
|
||||
new_version: ${{ steps.compute.outputs.new_version }}
|
||||
tag: ${{ steps.tag.outputs.tag }}
|
||||
bump_branch: ${{ steps.bump_branch.outputs.name }}
|
||||
steps:
|
||||
- name: Ensure workflow is running on main
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ "${GITHUB_REF_NAME}" != "main" ]]; then
|
||||
echo "This workflow must be run on the main branch. Current ref: ${GITHUB_REF_NAME}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: main
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Compute new version
|
||||
|
|
@ -75,57 +91,102 @@ jobs:
|
|||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "Updating MCPForUnity/package.json to $NEW_VERSION"
|
||||
jq ".version = \"${NEW_VERSION}\"" MCPForUnity/package.json > MCPForUnity/package.json.tmp
|
||||
mv MCPForUnity/package.json.tmp MCPForUnity/package.json
|
||||
echo "Updating all version references to $NEW_VERSION"
|
||||
python3 tools/update_versions.py --version "$NEW_VERSION"
|
||||
|
||||
echo "Updating Server/pyproject.toml to $NEW_VERSION"
|
||||
sed -i '0,/^version = ".*"/s//version = "'"$NEW_VERSION"'"/' "Server/pyproject.toml"
|
||||
|
||||
echo "Updating Server/README.md version references to v$NEW_VERSION"
|
||||
sed -i 's|git+https://github.com/CoplayDev/unity-mcp@v[0-9]\+\.[0-9]\+\.[0-9]\+#subdirectory=Server|git+https://github.com/CoplayDev/unity-mcp@v'"$NEW_VERSION"'#subdirectory=Server|g' Server/README.md
|
||||
|
||||
echo "Updating root README.md fixed version examples to v$NEW_VERSION"
|
||||
sed -i 's|https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v[0-9]\+\.[0-9]\+\.[0-9]\+|https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v'"$NEW_VERSION"'|g' README.md
|
||||
|
||||
echo "Updating docs/i18n/README-zh.md fixed version examples to v$NEW_VERSION"
|
||||
sed -i 's|https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v[0-9]\+\.[0-9]\+\.[0-9]\+|https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v'"$NEW_VERSION"'|g' docs/i18n/README-zh.md
|
||||
|
||||
- name: Commit and push changes
|
||||
- name: Commit version bump to a temporary branch
|
||||
id: bump_branch
|
||||
env:
|
||||
NEW_VERSION: ${{ steps.compute.outputs.new_version }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BRANCH="release/v${NEW_VERSION}"
|
||||
echo "name=$BRANCH" >> "$GITHUB_OUTPUT"
|
||||
|
||||
git config user.name "GitHub Actions"
|
||||
git config user.email "actions@github.com"
|
||||
git add MCPForUnity/package.json "Server/pyproject.toml" Server/README.md README.md docs/i18n/README-zh.md
|
||||
git checkout -b "$BRANCH"
|
||||
git add MCPForUnity/package.json manifest.json "Server/pyproject.toml" Server/README.md
|
||||
if git diff --cached --quiet; then
|
||||
echo "No version changes to commit."
|
||||
else
|
||||
git commit -m "chore: bump version to ${NEW_VERSION}"
|
||||
fi
|
||||
|
||||
BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
|
||||
echo "Pushing to branch: $BRANCH"
|
||||
echo "Pushing bump branch $BRANCH"
|
||||
git push origin "$BRANCH"
|
||||
|
||||
- name: Create and push tag
|
||||
- name: Create PR for version bump into main
|
||||
id: bump_pr
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
NEW_VERSION: ${{ steps.compute.outputs.new_version }}
|
||||
BRANCH: ${{ steps.bump_branch.outputs.name }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
PR_URL=$(gh pr create \
|
||||
--base main \
|
||||
--head "$BRANCH" \
|
||||
--title "chore: bump version to ${NEW_VERSION}" \
|
||||
--body "Automated version bump to ${NEW_VERSION}.")
|
||||
echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT"
|
||||
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
|
||||
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Enable auto-merge and merge PR
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PR_NUMBER: ${{ steps.bump_pr.outputs.pr_number }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Enable auto-merge (requires repo setting "Allow auto-merge")
|
||||
gh pr merge "$PR_NUMBER" --merge --auto || true
|
||||
# Wait for PR to be merged (poll up to 2 minutes)
|
||||
for i in {1..24}; do
|
||||
STATE=$(gh pr view "$PR_NUMBER" --json state -q '.state')
|
||||
if [[ "$STATE" == "MERGED" ]]; then
|
||||
echo "PR merged successfully."
|
||||
exit 0
|
||||
fi
|
||||
echo "Waiting for PR to merge... (state: $STATE)"
|
||||
sleep 5
|
||||
done
|
||||
echo "PR did not merge in time. Attempting direct merge..."
|
||||
gh pr merge "$PR_NUMBER" --merge
|
||||
|
||||
- name: Fetch merged main and create tag
|
||||
env:
|
||||
TAG: ${{ steps.tag.outputs.tag }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git fetch origin main
|
||||
git checkout main
|
||||
git pull origin main
|
||||
|
||||
echo "Preparing to create tag $TAG"
|
||||
|
||||
if git ls-remote --tags origin | grep -q "refs/tags/$TAG$"; then
|
||||
echo "Tag $TAG already exists on remote. Skipping tag creation."
|
||||
exit 0
|
||||
echo "Tag $TAG already exists on remote. Refusing to release." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git tag -a "$TAG" -m "Version ${TAG#v}"
|
||||
git push origin "$TAG"
|
||||
|
||||
- name: Clean up release branch
|
||||
if: always()
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
BRANCH: ${{ steps.bump_branch.outputs.name }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git push origin --delete "$BRANCH" || true
|
||||
|
||||
- name: Create GitHub release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
|
|
@ -133,6 +194,70 @@ jobs:
|
|||
name: ${{ steps.tag.outputs.tag }}
|
||||
generate_release_notes: true
|
||||
|
||||
sync_beta:
|
||||
name: Merge main back into beta via PR
|
||||
needs:
|
||||
- bump
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: main
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Create PR to merge main into beta
|
||||
id: sync_pr
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
NEW_VERSION: ${{ needs.bump.outputs.new_version }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Check if beta is behind main
|
||||
git fetch origin beta
|
||||
if git merge-base --is-ancestor origin/main origin/beta; then
|
||||
echo "beta is already up to date with main. Skipping PR."
|
||||
echo "skipped=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PR_URL=$(gh pr create \
|
||||
--base beta \
|
||||
--head main \
|
||||
--title "chore: sync main (v${NEW_VERSION}) into beta" \
|
||||
--body "Automated sync of version bump from main into beta.")
|
||||
echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT"
|
||||
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
|
||||
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
|
||||
echo "skipped=false" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Enable auto-merge and merge sync PR
|
||||
if: steps.sync_pr.outputs.skipped != 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PR_NUMBER: ${{ steps.sync_pr.outputs.pr_number }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Enable auto-merge (requires repo setting "Allow auto-merge")
|
||||
gh pr merge "$PR_NUMBER" --merge --auto || true
|
||||
# Wait for PR to be merged (poll up to 2 minutes)
|
||||
for i in {1..24}; do
|
||||
STATE=$(gh pr view "$PR_NUMBER" --json state -q '.state')
|
||||
if [[ "$STATE" == "MERGED" ]]; then
|
||||
echo "Sync PR merged successfully."
|
||||
exit 0
|
||||
fi
|
||||
echo "Waiting for sync PR to merge... (state: $STATE)"
|
||||
sleep 5
|
||||
done
|
||||
echo "Sync PR did not merge in time. Attempting direct merge..."
|
||||
gh pr merge "$PR_NUMBER" --merge
|
||||
|
||||
publish_docker:
|
||||
name: Publish Docker image
|
||||
needs:
|
||||
|
|
@ -194,3 +319,43 @@ jobs:
|
|||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages-dir: Server/dist/
|
||||
|
||||
publish_mcpb:
|
||||
name: Generate and publish MCPB bundle
|
||||
needs:
|
||||
- bump
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump.outputs.tag }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Generate MCPB bundle
|
||||
env:
|
||||
NEW_VERSION: ${{ needs.bump.outputs.new_version }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
python3 tools/generate_mcpb.py "$NEW_VERSION" \
|
||||
--output "unity-mcp-${NEW_VERSION}.mcpb" \
|
||||
--icon docs/images/coplay-logo.png
|
||||
|
||||
- name: Upload MCPB to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ needs.bump.outputs.tag }}
|
||||
files: unity-mcp-${{ needs.bump.outputs.new_version }}.mcpb
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
# MCPB Ignore File
|
||||
# This bundle uses uvx pattern - package downloaded from PyPI at runtime
|
||||
# Only manifest.json, icon.png, README.md, and LICENSE are needed
|
||||
|
||||
# Server source code (downloaded via uvx from PyPI)
|
||||
Server/
|
||||
|
||||
# Unity Client plugin (separate installation)
|
||||
MCPForUnity/
|
||||
|
||||
# Test projects
|
||||
TestProjects/
|
||||
|
||||
# Documentation folder
|
||||
docs/
|
||||
|
||||
# Custom Tools (shipped separately)
|
||||
CustomTools/
|
||||
|
||||
# Development scripts at root
|
||||
scripts/
|
||||
tools/
|
||||
|
||||
# Claude skill zip (separate distribution)
|
||||
claude_skill_unity.zip
|
||||
|
||||
# Development batch files
|
||||
deploy-dev.bat
|
||||
restore-dev.bat
|
||||
|
||||
# Test files at root
|
||||
test_unity_socket_framing.py
|
||||
mcp_source.py
|
||||
prune_tool_results.py
|
||||
|
||||
# Docker
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
Dockerfile
|
||||
|
||||
# Chinese README (keep English only)
|
||||
README-zh.md
|
||||
|
||||
# GitHub and CI
|
||||
.github/
|
||||
.claude/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Python artifacts
|
||||
*.pyc
|
||||
__pycache__/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
|
||||
# Environment
|
||||
.env*
|
||||
*.local
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Package management
|
||||
uv.lock
|
||||
poetry.lock
|
||||
requirements*.txt
|
||||
pyproject.toml
|
||||
|
||||
# Logs and temp
|
||||
*.log
|
||||
*.tmp
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
|
@ -36,9 +36,9 @@ In Unity: `Window > Package Manager > + > Add package from git URL...`
|
|||
> https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity
|
||||
> ```
|
||||
|
||||
**Need a stable/fixed version?** Use a tagged URL (requires uninstall to update):
|
||||
**Want the latest beta?** Use the beta branch:
|
||||
```text
|
||||
https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v9.1.0
|
||||
https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#beta
|
||||
```
|
||||
|
||||
<details>
|
||||
|
|
|
|||
|
|
@ -338,6 +338,36 @@ python3 tools/stress_mcp.py \
|
|||
4. **迭代** - 按需重复 1-3
|
||||
5. **Restore** 完成后用 `restore-dev.bat` 恢复原始文件
|
||||
|
||||
## 重要说明
|
||||
|
||||
### 更新工具和 Manifest
|
||||
|
||||
在 Unity 包中添加或修改 MCP 工具时:
|
||||
- 工具定义位于仓库根目录的 manifest.json 文件中
|
||||
- 在发布过程中,manifest.json 版本会自动与 MCPForUnity/package.json 保持同步
|
||||
- 如果在发布过程之外手动更新工具,请确保相应更新 manifest.json 版本
|
||||
- 使用综合版本更新脚本:`python3 tools/update_versions.py` 来同步项目中所有版本引用
|
||||
|
||||
`update_versions.py` 脚本会更新:
|
||||
- MCPForUnity/package.json(Unity 包版本)
|
||||
- manifest.json(MCP bundle manifest)
|
||||
- Server/pyproject.toml(Python 包版本)
|
||||
- Server/README.md(版本引用)
|
||||
- README.md(固定版本示例)
|
||||
- docs/i18n/README-zh.md(固定版本示例)
|
||||
|
||||
使用示例:
|
||||
```bash
|
||||
# 更新所有文件以匹配 package.json 版本
|
||||
python3 tools/update_versions.py
|
||||
|
||||
# 更新所有文件到指定版本
|
||||
python3 tools/update_versions.py --version 9.2.0
|
||||
|
||||
# 干运行以查看将要更新的内容
|
||||
python3 tools/update_versions.py --dry-run
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 运行 .bat 时出现 "Path not found"
|
||||
|
|
|
|||
|
|
@ -328,6 +328,36 @@ We provide a CI job to run a Natural Language Editing suite against the Unity te
|
|||
4. **Iterate** - repeat steps 1-3 as needed
|
||||
5. **Restore** original files when done using `restore-dev.bat`
|
||||
|
||||
## Important Notes
|
||||
|
||||
### Updating Tools and Manifest
|
||||
|
||||
When adding or modifying MCP tools in the Unity package:
|
||||
- Tool definitions are located in the manifest.json file at the repository root
|
||||
- The manifest.json version is automatically kept in sync with MCPForUnity/package.json during releases
|
||||
- If you manually update tools outside of the release process, ensure to update the manifest.json version accordingly
|
||||
- Use the comprehensive version update script: `python3 tools/update_versions.py` to sync all version references across the project
|
||||
|
||||
The `update_versions.py` script updates:
|
||||
- MCPForUnity/package.json (Unity package version)
|
||||
- manifest.json (MCP bundle manifest)
|
||||
- Server/pyproject.toml (Python package version)
|
||||
- Server/README.md (version references)
|
||||
- README.md (fixed version examples)
|
||||
- docs/i18n/README-zh.md (fixed version examples)
|
||||
|
||||
Usage examples:
|
||||
```bash
|
||||
# Update all files to match package.json version
|
||||
python3 tools/update_versions.py
|
||||
|
||||
# Update all files to a specific version
|
||||
python3 tools/update_versions.py --version 9.2.0
|
||||
|
||||
# Dry run to see what would be updated
|
||||
python3 tools/update_versions.py --dry-run
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Path not found" errors running the .bat file
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
# Releasing (Maintainers)
|
||||
|
||||
This repo uses a two-branch flow to keep `main` stable for users:
|
||||
|
||||
- `beta`: integration branch where feature PRs land
|
||||
- `main`: stable branch that should match the latest release tag
|
||||
|
||||
## Release checklist
|
||||
|
||||
### 1) Promote `beta` to `main` via PR
|
||||
|
||||
- Create a PR with:
|
||||
- base: `main`
|
||||
- compare: `beta`
|
||||
- Ensure required CI checks are green.
|
||||
- Merge the PR.
|
||||
|
||||
Release note quality depends on how you merge:
|
||||
|
||||
- Squash-merging feature PRs into `beta` is OK.
|
||||
- Avoid squash-merging the `beta -> main` promotion PR. Prefer a merge commit (or rebase merge) so GitHub can produce better auto-generated release notes.
|
||||
|
||||
### 2) Run the Release workflow (manual)
|
||||
|
||||
- Go to **GitHub → Actions → Release**
|
||||
- Click **Run workflow**
|
||||
- Select:
|
||||
- `patch`, `minor`, or `major`
|
||||
- Run it on branch: `main`
|
||||
|
||||
What the workflow does:
|
||||
|
||||
1. Creates a temporary `release/vX.Y.Z` branch with the version bump commit
|
||||
2. Opens a PR from that branch into `main`
|
||||
3. Auto-merges the PR (or waits for required checks, then merges)
|
||||
4. Creates an annotated tag `vX.Y.Z` on the merged commit
|
||||
5. Creates a GitHub Release for the tag
|
||||
6. Publishes artifacts (Docker / PyPI / MCPB)
|
||||
7. Opens a PR to merge `main` back into `beta` (so `beta` gets the bump)
|
||||
8. Auto-merges the sync PR
|
||||
9. Cleans up the temporary release branch
|
||||
|
||||
### 3) Verify release outputs
|
||||
|
||||
- Confirm a new tag exists: `vX.Y.Z`
|
||||
- Confirm a GitHub Release exists for the tag
|
||||
- Confirm artifacts:
|
||||
- Docker image published with version `X.Y.Z`
|
||||
- PyPI package published (if configured)
|
||||
- `unity-mcp-X.Y.Z.mcpb` attached to the GitHub Release
|
||||
|
||||
## Required repo settings
|
||||
|
||||
### Branch protection (Rulesets)
|
||||
|
||||
The release workflow uses PRs instead of direct pushes, so it works with strict branch protection. No bypass actors are required.
|
||||
|
||||
Recommended ruleset for `main`:
|
||||
|
||||
- Require PR before merging
|
||||
- Allowed merge methods: `merge`, `rebase` (no squash for promotion PRs)
|
||||
- Required approvals: `0` (so automated PRs can merge without human review)
|
||||
- Optionally require status checks
|
||||
|
||||
Recommended ruleset for `beta`:
|
||||
|
||||
- Require PR before merging
|
||||
- Allowed merge methods: `squash` (for feature PRs)
|
||||
- Required approvals: `0` (so the sync PR can auto-merge)
|
||||
|
||||
### Enable auto-merge (required)
|
||||
|
||||
The workflow uses `gh pr merge --auto` to automatically merge PRs once checks pass.
|
||||
|
||||
To enable:
|
||||
|
||||
1. Go to **Settings → General**
|
||||
2. Scroll to **Pull Requests**
|
||||
3. Check **Allow auto-merge**
|
||||
|
||||
Without this setting, the workflow will fall back to direct merge attempts, which may fail if branch protection requires checks.
|
||||
|
||||
## Failure modes and recovery
|
||||
|
||||
### Tag already exists
|
||||
|
||||
The workflow fails if the computed tag already exists. Pick a different bump type or investigate why a tag already exists for that version.
|
||||
|
||||
### Bump PR fails to merge
|
||||
|
||||
If the version bump PR cannot be merged (e.g., required checks fail):
|
||||
|
||||
- The workflow will fail before creating a tag.
|
||||
- Fix the issue, then either:
|
||||
- Manually merge the PR and create the tag/release, or
|
||||
- Close the PR, delete the `release/vX.Y.Z` branch, and re-run the workflow.
|
||||
|
||||
### Sync PR (`main -> beta`) fails
|
||||
|
||||
If the sync PR has merge conflicts:
|
||||
|
||||
- The workflow will fail after the release is published (artifacts are already out).
|
||||
- Manually resolve conflicts in the sync PR and merge it.
|
||||
|
||||
### Leftover release branch
|
||||
|
||||
If the workflow fails mid-run, a `release/vX.Y.Z` branch may remain. Delete it manually before re-running:
|
||||
|
||||
```bash
|
||||
git push origin --delete release/vX.Y.Z
|
||||
```
|
||||
|
|
@ -36,9 +36,9 @@
|
|||
> https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity
|
||||
> ```
|
||||
|
||||
**需要一个稳定/固定版本?** 使用带 tag 的 URL(更新时需要卸载才能更新):
|
||||
**想要最新的 beta 版本?** 使用 beta 分支:
|
||||
```text
|
||||
https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v9.1.0
|
||||
https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#beta
|
||||
```
|
||||
|
||||
<details>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"manifest_version": "0.3",
|
||||
"name": "Unity MCP",
|
||||
"version": "9.1.0",
|
||||
"description": "AI-powered Unity Editor automation via MCP - manage GameObjects, scripts, materials, scenes, prefabs, VFX, and run tests",
|
||||
"author": {
|
||||
"name": "Coplay",
|
||||
"url": "https://www.coplay.dev"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CoplayDev/unity-mcp"
|
||||
},
|
||||
"homepage": "https://www.coplay.dev",
|
||||
"documentation": "https://github.com/CoplayDev/unity-mcp#readme",
|
||||
"support": "https://github.com/CoplayDev/unity-mcp/issues",
|
||||
"icon": "coplay-logo.png",
|
||||
"server": {
|
||||
"type": "python",
|
||||
"entry_point": "Server/src/main.py",
|
||||
"mcp_config": {
|
||||
"command": "uvx",
|
||||
"args": ["--from", "mcpforunityserver", "mcp-for-unity"],
|
||||
"env": {}
|
||||
}
|
||||
},
|
||||
"tools": [
|
||||
{"name": "batch_execute", "description": "Execute multiple Unity operations in a single batch"},
|
||||
{"name": "debug_request_context", "description": "Debug and inspect MCP request context"},
|
||||
{"name": "execute_custom_tool", "description": "Execute custom Unity Editor tools registered by the project"},
|
||||
{"name": "execute_menu_item", "description": "Execute Unity Editor menu items"},
|
||||
{"name": "find_gameobjects", "description": "Find GameObjects in the scene by various criteria"},
|
||||
{"name": "find_in_file", "description": "Search for content within Unity project files"},
|
||||
{"name": "manage_asset", "description": "Create, modify, search, and organize Unity assets"},
|
||||
{"name": "manage_components", "description": "Add, remove, and configure GameObject components"},
|
||||
{"name": "manage_editor", "description": "Control Unity Editor state, play mode, and preferences"},
|
||||
{"name": "manage_gameobject", "description": "Create, modify, transform, and delete GameObjects"},
|
||||
{"name": "manage_material", "description": "Create and modify Unity materials and shaders"},
|
||||
{"name": "manage_prefabs", "description": "Create, instantiate, unpack, and modify prefabs"},
|
||||
{"name": "manage_scene", "description": "Load, save, query hierarchy, and manage Unity scenes"},
|
||||
{"name": "manage_script", "description": "Create, read, and modify C# scripts"},
|
||||
{"name": "manage_scriptable_object", "description": "Create and modify ScriptableObjects"},
|
||||
{"name": "manage_shader", "description": "Work with Unity shaders"},
|
||||
{"name": "manage_vfx", "description": "Manage Visual Effects, particle systems, and trails"},
|
||||
{"name": "read_console", "description": "Read Unity Editor console output (logs, warnings, errors)"},
|
||||
{"name": "refresh_unity", "description": "Refresh Unity Editor asset database"},
|
||||
{"name": "run_tests", "description": "Run Unity Test Framework tests"},
|
||||
{"name": "get_test_job", "description": "Get status of async test job"},
|
||||
{"name": "script_apply_edits", "description": "Apply code edits to C# scripts with validation"},
|
||||
{"name": "set_active_instance", "description": "Set the active Unity Editor instance for multi-instance workflows"},
|
||||
{"name": "apply_text_edits", "description": "Apply text edits to script content"},
|
||||
{"name": "create_script", "description": "Create new C# scripts"},
|
||||
{"name": "delete_script", "description": "Delete C# scripts"},
|
||||
{"name": "validate_script", "description": "Validate C# script syntax and compilation"},
|
||||
{"name": "manage_script_capabilities", "description": "Query script management capabilities"},
|
||||
{"name": "get_sha", "description": "Get SHA hash of script content"}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# LLM Prompt for Updating Documentation
|
||||
|
||||
Copy and paste this prompt into your LLM when you need to update documentation after adding/removing/modifying MCP tools or resources.
|
||||
|
||||
## Example Usage
|
||||
|
||||
After adding a new tool called "manage_new_feature" and a new resource called "feature_resource", you would:
|
||||
1. Copy the prompt in the section below
|
||||
2. Paste it into your LLM
|
||||
3. The LLM will analyze the codebase and update all documentation files
|
||||
4. Review the changes and run the check script to verify
|
||||
|
||||
This ensures all documentation stays in sync across the repository.
|
||||
|
||||
---
|
||||
|
||||
## Prompt
|
||||
|
||||
I've just made changes to MCP tools or resources in this Unity MCP repository. Please update all documentation files to keep them in sync.
|
||||
|
||||
Here's what you need to do:
|
||||
|
||||
1. **Check the current tools and resources** by examining:
|
||||
- `Server/src/services/tools/` - Python tool implementations (look for @mcp_for_unity_tool decorators)
|
||||
- `Server/src/services/resources/` - Python resource implementations (look for @mcp_for_unity_resource decorators)
|
||||
|
||||
2. **Update these files**:
|
||||
|
||||
a) **manifest.json** (root directory)
|
||||
- Update the "tools" array (lines 27-57)
|
||||
- Each tool needs: {"name": "tool_name", "description": "Brief description"}
|
||||
- Keep tools in alphabetical order
|
||||
- Note: Resources are not listed in manifest.json, only tools
|
||||
|
||||
b) **README.md** (root directory)
|
||||
- Update "Available Tools" section (around line 78-79)
|
||||
- Format: `tool1` • `tool2` • `tool3`
|
||||
- Keep the same order as manifest.json
|
||||
|
||||
c) **README.md** - Resources section
|
||||
- Update "Available Resources" section (around line 81-82)
|
||||
- Format: `resource1` • `resource2` • `resource3`
|
||||
- Resources come from Server/src/services/resources/ files
|
||||
- Keep resources in alphabetical order
|
||||
|
||||
d) **docs/i18n/README-zh.md**
|
||||
- Find and update the "可用工具" (Available Tools) section
|
||||
- Find and update the "可用资源" (Available Resources) section
|
||||
- Keep tool/resource names in English, but you can translate descriptions if helpful
|
||||
|
||||
3. **Important formatting rules**:
|
||||
- Use backticks around tool/resource names
|
||||
- Separate items with • (bullet point)
|
||||
- Keep lists on single lines when possible
|
||||
- Maintain alphabetical ordering
|
||||
- Tools and resources are listed separately in documentation
|
||||
|
||||
4. **After updating**, run this check to verify:
|
||||
```bash
|
||||
python3 tools/check_docs_sync.py
|
||||
```
|
||||
It should show "All documentation is synchronized!"
|
||||
|
||||
Please show me the exact changes you're making to each file, and explain any discrepancies you find.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Generate MCPB bundle for Unity MCP.
|
||||
|
||||
This script creates a Model Context Protocol Bundle (.mcpb) file
|
||||
for distribution as a GitHub release artifact.
|
||||
|
||||
Usage:
|
||||
python3 tools/generate_mcpb.py VERSION [--output FILE] [--icon PATH]
|
||||
|
||||
Examples:
|
||||
python3 tools/generate_mcpb.py 9.0.8
|
||||
python3 tools/generate_mcpb.py 9.0.8 --output unity-mcp-9.0.8.mcpb
|
||||
python3 tools/generate_mcpb.py 9.0.8 --icon docs/images/coplay-logo.png
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
DEFAULT_ICON = REPO_ROOT / "docs" / "images" / "coplay-logo.png"
|
||||
MANIFEST_TEMPLATE = REPO_ROOT / "manifest.json"
|
||||
|
||||
|
||||
def create_manifest(version: str, icon_filename: str) -> dict:
|
||||
"""Create manifest.json content with the specified version."""
|
||||
if not MANIFEST_TEMPLATE.exists():
|
||||
raise FileNotFoundError(f"Manifest template not found: {MANIFEST_TEMPLATE}")
|
||||
|
||||
manifest = json.loads(MANIFEST_TEMPLATE.read_text(encoding="utf-8"))
|
||||
manifest["version"] = version
|
||||
manifest["icon"] = icon_filename
|
||||
return manifest
|
||||
|
||||
|
||||
def generate_mcpb(
|
||||
version: str,
|
||||
output_path: Path,
|
||||
icon_path: Path,
|
||||
) -> Path:
|
||||
"""Generate MCPB bundle file.
|
||||
|
||||
Args:
|
||||
version: Semantic version string (e.g., "9.0.8")
|
||||
output_path: Output path for the .mcpb file
|
||||
icon_path: Path to the icon file
|
||||
|
||||
Returns:
|
||||
Path to the generated .mcpb file
|
||||
"""
|
||||
if not icon_path.exists():
|
||||
raise FileNotFoundError(f"Icon not found: {icon_path}")
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
build_dir = Path(tmpdir) / "mcpb-build"
|
||||
build_dir.mkdir()
|
||||
|
||||
# Copy icon
|
||||
icon_filename = icon_path.name
|
||||
shutil.copy2(icon_path, build_dir / icon_filename)
|
||||
|
||||
# Create manifest with version
|
||||
manifest = create_manifest(version, icon_filename)
|
||||
manifest_path = build_dir / "manifest.json"
|
||||
manifest_path.write_text(
|
||||
json.dumps(manifest, indent=2, ensure_ascii=False) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
# Copy LICENSE and README if they exist
|
||||
for filename in ["LICENSE", "README.md"]:
|
||||
src = REPO_ROOT / filename
|
||||
if src.exists():
|
||||
shutil.copy2(src, build_dir / filename)
|
||||
|
||||
# Pack using mcpb CLI
|
||||
# Syntax: mcpb pack [directory] [output]
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["npx", "@anthropic-ai/mcpb", "pack", ".", str(output_path.absolute())],
|
||||
cwd=build_dir,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
print(result.stdout)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"MCPB pack failed:\n{e.stderr}", file=sys.stderr)
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
print(
|
||||
"Error: npx not found. Please install Node.js and npm.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
raise
|
||||
|
||||
if not output_path.exists():
|
||||
raise RuntimeError(f"MCPB file was not created: {output_path}")
|
||||
|
||||
print(f"Generated: {output_path} ({output_path.stat().st_size:,} bytes)")
|
||||
return output_path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate MCPB bundle for Unity MCP",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__doc__,
|
||||
)
|
||||
parser.add_argument(
|
||||
"version",
|
||||
help="Version string for the bundle (e.g., 9.0.8)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
"-o",
|
||||
type=Path,
|
||||
help="Output path for the .mcpb file (default: unity-mcp-VERSION.mcpb)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--icon",
|
||||
type=Path,
|
||||
default=DEFAULT_ICON,
|
||||
help=f"Path to icon file (default: {DEFAULT_ICON.relative_to(REPO_ROOT)})",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Default output name
|
||||
if args.output is None:
|
||||
args.output = Path(f"unity-mcp-{args.version}.mcpb")
|
||||
|
||||
try:
|
||||
generate_mcpb(args.version, args.output, args.icon)
|
||||
return 0
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Update version across all project files.
|
||||
|
||||
This script updates the version in all files that need it:
|
||||
- MCPForUnity/package.json (Unity package version)
|
||||
- manifest.json (MCP bundle manifest)
|
||||
- Server/pyproject.toml (Python package version)
|
||||
- Server/README.md (version references)
|
||||
- README.md (fixed version examples)
|
||||
- docs/i18n/README-zh.md (fixed version examples)
|
||||
|
||||
Usage:
|
||||
python3 tools/update_versions.py [--dry-run] [--version VERSION]
|
||||
|
||||
Options:
|
||||
--dry-run: Show what would be updated without making changes
|
||||
--version: Specify version to use (auto-detected from package.json if not provided)
|
||||
|
||||
Examples:
|
||||
# Update all files to match package.json version
|
||||
python3 tools/update_versions.py
|
||||
|
||||
# Update all files to a specific version
|
||||
python3 tools/update_versions.py --version 9.2.0
|
||||
|
||||
# Dry run to see what would be updated
|
||||
python3 tools/update_versions.py --dry-run
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
PACKAGE_JSON = REPO_ROOT / "MCPForUnity" / "package.json"
|
||||
MANIFEST_JSON = REPO_ROOT / "manifest.json"
|
||||
PYPROJECT_TOML = REPO_ROOT / "Server" / "pyproject.toml"
|
||||
SERVER_README = REPO_ROOT / "Server" / "README.md"
|
||||
ROOT_README = REPO_ROOT / "README.md"
|
||||
ZH_README = REPO_ROOT / "docs" / "i18n" / "README-zh.md"
|
||||
|
||||
|
||||
def load_package_version() -> str:
|
||||
"""Load version from package.json."""
|
||||
if not PACKAGE_JSON.exists():
|
||||
raise FileNotFoundError(f"Package file not found: {PACKAGE_JSON}")
|
||||
|
||||
package_data = json.loads(PACKAGE_JSON.read_text(encoding="utf-8"))
|
||||
version = package_data.get("version")
|
||||
|
||||
if not version:
|
||||
raise ValueError("No version found in package.json")
|
||||
|
||||
return version
|
||||
|
||||
|
||||
def update_package_json(new_version: str, dry_run: bool = False) -> bool:
|
||||
"""Update version in MCPForUnity/package.json."""
|
||||
if not PACKAGE_JSON.exists():
|
||||
print(f"Warning: {PACKAGE_JSON.relative_to(REPO_ROOT)} not found")
|
||||
return False
|
||||
|
||||
package_data = json.loads(PACKAGE_JSON.read_text(encoding="utf-8"))
|
||||
current_version = package_data.get("version", "unknown")
|
||||
|
||||
if current_version == new_version:
|
||||
print(f"✓ {PACKAGE_JSON.relative_to(REPO_ROOT)} already at v{new_version}")
|
||||
return False
|
||||
|
||||
print(
|
||||
f"Updating {PACKAGE_JSON.relative_to(REPO_ROOT)}: {current_version} → {new_version}")
|
||||
|
||||
if not dry_run:
|
||||
package_data["version"] = new_version
|
||||
PACKAGE_JSON.write_text(
|
||||
json.dumps(package_data, indent=2, ensure_ascii=False) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_manifest_json(new_version: str, dry_run: bool = False) -> bool:
|
||||
"""Update version in manifest.json."""
|
||||
if not MANIFEST_JSON.exists():
|
||||
print(f"Warning: {MANIFEST_JSON.relative_to(REPO_ROOT)} not found")
|
||||
return False
|
||||
|
||||
manifest = json.loads(MANIFEST_JSON.read_text(encoding="utf-8"))
|
||||
current_version = manifest.get("version", "unknown")
|
||||
|
||||
if current_version == new_version:
|
||||
print(f"✓ {MANIFEST_JSON.relative_to(REPO_ROOT)} already at v{new_version}")
|
||||
return False
|
||||
|
||||
print(
|
||||
f"Updating {MANIFEST_JSON.relative_to(REPO_ROOT)}: {current_version} → {new_version}")
|
||||
|
||||
if not dry_run:
|
||||
manifest["version"] = new_version
|
||||
MANIFEST_JSON.write_text(
|
||||
json.dumps(manifest, indent=2, ensure_ascii=False) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_pyproject_toml(new_version: str, dry_run: bool = False) -> bool:
|
||||
"""Update version in Server/pyproject.toml."""
|
||||
if not PYPROJECT_TOML.exists():
|
||||
print(f"Warning: {PYPROJECT_TOML.relative_to(REPO_ROOT)} not found")
|
||||
return False
|
||||
|
||||
content = PYPROJECT_TOML.read_text(encoding="utf-8")
|
||||
|
||||
# Find current version
|
||||
version_match = re.search(r'^version = "([^"]+)"', content, re.MULTILINE)
|
||||
if not version_match:
|
||||
print(
|
||||
f"Warning: Could not find version in {PYPROJECT_TOML.relative_to(REPO_ROOT)}")
|
||||
return False
|
||||
|
||||
current_version = version_match.group(1)
|
||||
|
||||
if current_version == new_version:
|
||||
print(f"✓ {PYPROJECT_TOML.relative_to(REPO_ROOT)} already at v{new_version}")
|
||||
return False
|
||||
|
||||
print(
|
||||
f"Updating {PYPROJECT_TOML.relative_to(REPO_ROOT)}: {current_version} → {new_version}")
|
||||
|
||||
if not dry_run:
|
||||
# Replace only the first occurrence (the version field)
|
||||
content = re.sub(
|
||||
r'^version = ".*"', f'version = "{new_version}"', content, count=1, flags=re.MULTILINE)
|
||||
PYPROJECT_TOML.write_text(content, encoding="utf-8")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_server_readme(new_version: str, dry_run: bool = False) -> bool:
|
||||
"""Update version references in Server/README.md."""
|
||||
if not SERVER_README.exists():
|
||||
print(f"Warning: {SERVER_README.relative_to(REPO_ROOT)} not found")
|
||||
return False
|
||||
|
||||
content = SERVER_README.read_text(encoding="utf-8")
|
||||
|
||||
# Pattern to match git+https URLs with version tags
|
||||
pattern = r'git\+https://github\.com/CoplayDev/unity-mcp@v[0-9]+\.[0-9]+\.[0-9]+#subdirectory=Server'
|
||||
replacement = f'git+https://github.com/CoplayDev/unity-mcp@v{new_version}#subdirectory=Server'
|
||||
|
||||
if not re.search(pattern, content):
|
||||
print(
|
||||
f"✓ {SERVER_README.relative_to(REPO_ROOT)} has no version references to update")
|
||||
return False
|
||||
|
||||
print(
|
||||
f"Updating version references in {SERVER_README.relative_to(REPO_ROOT)}")
|
||||
|
||||
if not dry_run:
|
||||
content = re.sub(pattern, replacement, content)
|
||||
SERVER_README.write_text(content, encoding="utf-8")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_root_readme(new_version: str, dry_run: bool = False) -> bool:
|
||||
"""Update fixed version examples in README.md."""
|
||||
if not ROOT_README.exists():
|
||||
print(f"Warning: {ROOT_README.relative_to(REPO_ROOT)} not found")
|
||||
return False
|
||||
|
||||
content = ROOT_README.read_text(encoding="utf-8")
|
||||
|
||||
# Pattern to match git URLs with fixed version tags
|
||||
pattern = r'https://github\.com/CoplayDev/unity-mcp\.git\?path=/MCPForUnity#v[0-9]+\.[0-9]+\.[0-9]+'
|
||||
replacement = f'https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v{new_version}'
|
||||
|
||||
if not re.search(pattern, content):
|
||||
print(
|
||||
f"✓ {ROOT_README.relative_to(REPO_ROOT)} has no version references to update")
|
||||
return False
|
||||
|
||||
print(
|
||||
f"Updating version references in {ROOT_README.relative_to(REPO_ROOT)}")
|
||||
|
||||
if not dry_run:
|
||||
content = re.sub(pattern, replacement, content)
|
||||
ROOT_README.write_text(content, encoding="utf-8")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def update_zh_readme(new_version: str, dry_run: bool = False) -> bool:
|
||||
"""Update fixed version examples in docs/i18n/README-zh.md."""
|
||||
if not ZH_README.exists():
|
||||
print(f"Warning: {ZH_README.relative_to(REPO_ROOT)} not found")
|
||||
return False
|
||||
|
||||
content = ZH_README.read_text(encoding="utf-8")
|
||||
|
||||
# Pattern to match git URLs with fixed version tags
|
||||
pattern = r'https://github\.com/CoplayDev/unity-mcp\.git\?path=/MCPForUnity#v[0-9]+\.[0-9]+\.[0-9]+'
|
||||
replacement = f'https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v{new_version}'
|
||||
|
||||
if not re.search(pattern, content):
|
||||
print(
|
||||
f"✓ {ZH_README.relative_to(REPO_ROOT)} has no version references to update")
|
||||
return False
|
||||
|
||||
print(f"Updating version references in {ZH_README.relative_to(REPO_ROOT)}")
|
||||
|
||||
if not dry_run:
|
||||
content = re.sub(pattern, replacement, content)
|
||||
ZH_README.write_text(content, encoding="utf-8")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Update version across all project files",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__doc__,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Show what would be updated without making changes",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
help="Version to set (auto-detected from package.json if not provided)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
# Determine version
|
||||
if args.version:
|
||||
version = args.version
|
||||
print(f"Using specified version: {version}")
|
||||
else:
|
||||
version = load_package_version()
|
||||
print(f"Auto-detected version from package.json: {version}")
|
||||
|
||||
# Update all files
|
||||
updates_made = []
|
||||
|
||||
# Always update package.json if a version is specified
|
||||
if args.version:
|
||||
if update_package_json(version, args.dry_run):
|
||||
updates_made.append("MCPForUnity/package.json")
|
||||
|
||||
if update_manifest_json(version, args.dry_run):
|
||||
updates_made.append("manifest.json")
|
||||
|
||||
if update_pyproject_toml(version, args.dry_run):
|
||||
updates_made.append("Server/pyproject.toml")
|
||||
|
||||
if update_server_readme(version, args.dry_run):
|
||||
updates_made.append("Server/README.md")
|
||||
|
||||
|
||||
# Summary
|
||||
if args.dry_run:
|
||||
print("\nDry run complete. No files were modified.")
|
||||
else:
|
||||
if updates_made:
|
||||
print(
|
||||
f"\nUpdated {len(updates_made)} files: {', '.join(updates_made)}")
|
||||
else:
|
||||
print("\nAll files already at the correct version.")
|
||||
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Reference in New Issue