Merge pull request #17 from PatrykIti/feat/comprehensive-project-improvements

ci+docker: Comprehensive project improvements - CI/CD automation, documentation system, multi-platform support
This commit is contained in:
Beehive Innovations
2025-06-13 15:25:07 +04:00
committed by GitHub
11 changed files with 940 additions and 1 deletions

81
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: 🐞 Bug Report
description: Create a report to help us improve
labels: ["bug", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to file a bug report! Please provide as much detail as possible to help us reproduce and fix the issue.
- type: input
id: version
attributes:
label: Project Version
description: "Which version are you using? (e.g., Docker image tag like `latest` or `v1.2.3`, or a git commit SHA)"
placeholder: "e.g., ghcr.io/beehiveinnovations/zen-mcp-server:latest"
validations:
required: true
- type: textarea
id: description
attributes:
label: Bug Description
description: A clear and concise description of what the bug is.
placeholder: "When I run the `codereview` tool on a Python file with syntax errors, it hangs instead of reporting an error."
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: Steps to Reproduce
description: "Provide the exact steps to reproduce the behavior. Include the full command you ran."
placeholder: |
1. Create a file `test.py` with the content `def my_func(a,b)`
2. Run the command: `docker exec -i zen-mcp-server python server.py`
3. Use Claude Desktop with gemini codereview tool on test.py
4. Observe the behavior...
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen.
placeholder: "I expected the tool to exit with an error message about the invalid Python syntax."
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant Log Output
description: "Please copy and paste any relevant log output. This will be automatically formatted into a code block."
render: shell
- type: dropdown
id: environment
attributes:
label: Operating System
description: What operating system are you running the Docker client on?
options:
- Windows (via WSL2)
- Windows (via Docker Desktop)
- macOS (Intel)
- macOS (Apple Silicon)
- Linux
validations:
required: true
- type: checkboxes
id: no-duplicate-issues
attributes:
label: Sanity Checks
description: "Before submitting, please confirm the following:"
options:
- label: I have searched the existing issues and this is not a duplicate.
required: true
- label: I have confirmed that my `GEMINI_API_KEY` is set correctly.
required: true

12
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
blank_issues_enabled: false
contact_links:
- name: 💬 General Discussion
url: https://github.com/BeehiveInnovations/zen-mcp-server/discussions
about: Ask questions, share ideas, or discuss usage patterns with the community
- name: 📚 Documentation
url: https://github.com/BeehiveInnovations/zen-mcp-server/blob/main/README.md
about: Check the README for setup instructions and usage examples
- name: 🤝 Contributing Guide
url: https://github.com/BeehiveInnovations/zen-mcp-server/blob/main/CONTRIBUTING.md
about: Learn how to contribute to the project

View File

@@ -0,0 +1,68 @@
name: 📖 Documentation Improvement
description: Report an issue or suggest an improvement for the documentation
labels: ["documentation", "good first issue"]
body:
- type: input
id: location
attributes:
label: Documentation Location
description: "Which file or page has the issue? (e.g., README.md, CONTRIBUTING.md, CLAUDE.md)"
placeholder: "e.g., README.md"
validations:
required: true
- type: dropdown
id: issue-type
attributes:
label: Type of Documentation Issue
description: What kind of documentation improvement is this?
options:
- Typo or grammar error
- Unclear or confusing explanation
- Outdated information
- Missing information
- Code example doesn't work
- Installation/setup instructions unclear
- Tool usage examples need improvement
- Other
validations:
required: true
- type: textarea
id: problem
attributes:
label: What is wrong with the documentation?
description: "Please describe the problem. Be specific about what is unclear, incorrect, or missing."
placeholder: "The Docker setup command in the README is missing the `--pull=always` flag, which means users might use an outdated image version."
validations:
required: true
- type: textarea
id: suggestion
attributes:
label: Suggested Improvement
description: "How can we make it better? If you can, please provide the exact text or changes you'd like to see."
placeholder: |
Change:
```
docker run ghcr.io/beehiveinnovations/zen-mcp-server:latest
```
To:
```
docker run --pull=always ghcr.io/beehiveinnovations/zen-mcp-server:latest
```
- type: dropdown
id: audience
attributes:
label: Target Audience
description: Which audience would benefit most from this improvement?
options:
- New users (first-time setup)
- Developers (contributing to the project)
- Advanced users (complex workflows)
- All users
validations:
required: true

View File

@@ -0,0 +1,52 @@
name: ✨ Feature Request
description: Suggest an idea for this project
labels: ["enhancement", "needs-triage"]
body:
- type: textarea
id: problem-description
attributes:
label: What problem is this feature trying to solve?
description: "A clear and concise description of the problem or user need. Why is this change needed?"
placeholder: "Currently, I can only use one Gemini tool at a time. I want to be able to chain multiple tools together (e.g., analyze -> codereview -> thinkdeep) in a single workflow."
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen. How would it work from a user's perspective?
placeholder: "I'd like to be able to specify a workflow like 'analyze src/ then codereview the findings then use thinkdeep to suggest improvements' in a single command or configuration."
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
placeholder: "I considered manually running each tool sequentially, but automatic workflow chaining would be more efficient and ensure context is preserved between steps."
- type: dropdown
id: feature-type
attributes:
label: Feature Category
description: What type of enhancement is this?
options:
- New Gemini tool (chat, codereview, debug, etc.)
- Workflow improvement
- Integration enhancement
- Performance optimization
- User experience improvement
- Documentation enhancement
- Other
validations:
required: true
- type: checkboxes
id: contribution
attributes:
label: Contribution
options:
- label: I am willing to submit a Pull Request to implement this feature.

View File

@@ -0,0 +1,75 @@
name: 🛠️ New Gemini Tool Proposal
description: Propose a new Gemini MCP tool (e.g., `summarize`, `testgen`, `refactor`)
labels: ["enhancement", "new-tool"]
body:
- type: input
id: tool-name
attributes:
label: Proposed Tool Name
description: "What would the tool be called? (e.g., `summarize`, `testgen`, `refactor`)"
placeholder: "e.g., `docgen`"
validations:
required: true
- type: textarea
id: purpose
attributes:
label: What is the primary purpose of this tool?
description: "Explain the tool's core function and the value it provides to developers using Claude + Gemini."
placeholder: "This tool will automatically generate comprehensive documentation from code, extracting class and function signatures, docstrings, and creating usage examples."
validations:
required: true
- type: textarea
id: example-usage
attributes:
label: Example Usage in Claude Desktop
description: "Show how a user would invoke this tool through Claude and what the expected output would look like."
placeholder: |
**User prompt to Claude:**
"Use gemini to generate documentation for my entire src/ directory"
**Expected Gemini tool behavior:**
- Analyze all Python files in src/
- Extract classes, functions, and their docstrings
- Generate structured markdown documentation
- Include usage examples where possible
- Return organized documentation with table of contents
render: markdown
validations:
required: true
- type: dropdown
id: tool-category
attributes:
label: Tool Category
description: What category does this tool fit into?
options:
- Code Analysis (like analyze)
- Code Quality (like codereview)
- Code Generation/Refactoring
- Documentation Generation
- Testing Support
- Debugging Support (like debug)
- Workflow Automation
- Architecture Planning (like thinkdeep)
- Other
validations:
required: true
- type: textarea
id: system-prompt
attributes:
label: Proposed System Prompt (Optional)
description: "If you have ideas for how Gemini should be prompted for this tool, share them here."
placeholder: |
You are an expert technical documentation generator. Your task is to create comprehensive, user-friendly documentation from source code...
- type: checkboxes
id: contribution
attributes:
label: Contribution
options:
- label: I am willing to submit a Pull Request to implement this new tool.
- label: I have checked that this tool doesn't overlap significantly with existing tools (analyze, codereview, debug, thinkdeep, chat).

60
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,60 @@
## PR Title Format
**Please ensure your PR title follows one of these formats:**
### Version Bumping Prefixes (trigger Docker build + version bump):
- `feat: <description>` - New features (triggers MINOR version bump)
- `fix: <description>` - Bug fixes (triggers PATCH version bump)
- `breaking: <description>` or `BREAKING CHANGE: <description>` - Breaking changes (triggers MAJOR version bump)
- `perf: <description>` - Performance improvements (triggers PATCH version bump)
- `refactor: <description>` - Code refactoring (triggers PATCH version bump)
### Non-Version Prefixes (no version bump):
- `docs: <description>` - Documentation only
- `chore: <description>` - Maintenance tasks
- `test: <description>` - Test additions/changes
- `ci: <description>` - CI/CD changes
- `style: <description>` - Code style changes
### Docker Build Options:
- `docker: <description>` - Force Docker build without version bump
- `docs+docker: <description>` - Documentation + Docker build
- `chore+docker: <description>` - Maintenance + Docker build
- `test+docker: <description>` - Tests + Docker build
- `ci+docker: <description>` - CI changes + Docker build
- `style+docker: <description>` - Style changes + Docker build
## Description
Please provide a clear and concise description of what this PR does.
## Changes Made
- [ ] List the specific changes made
- [ ] Include any breaking changes
- [ ] Note any dependencies added/removed
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass (if applicable)
- [ ] Manual testing completed
- [ ] Documentation updated (if needed)
## Related Issues
Fixes #(issue number)
## Checklist
- [ ] PR title follows the format guidelines above
- [ ] Code follows the project's style guidelines
- [ ] Self-review completed
- [ ] Tests added/updated as needed
- [ ] Documentation updated as needed
- [ ] All tests passing
- [ ] Ready for review
## Additional Notes
Any additional information that reviewers should know.

248
.github/workflows/auto-version.yml vendored Normal file
View File

@@ -0,0 +1,248 @@
name: Auto Version
on:
pull_request:
types: [closed]
branches: [main]
jobs:
version:
# Only run if PR was merged (not just closed)
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.PAT }}
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Determine version bump type
id: bump_type
run: |
PR_TITLE="${{ github.event.pull_request.title }}"
echo "PR Title: $PR_TITLE"
# Convert to lowercase for case-insensitive matching
PR_TITLE_LOWER=$(echo "$PR_TITLE" | tr '[:upper:]' '[:lower:]')
# Determine bump type based on PR title prefix
if [[ "$PR_TITLE_LOWER" =~ ^(breaking|breaking[[:space:]]change): ]]; then
echo "Detected BREAKING CHANGE - major version bump"
echo "bump_type=major" >> $GITHUB_OUTPUT
echo "should_bump=true" >> $GITHUB_OUTPUT
echo "should_build_docker=true" >> $GITHUB_OUTPUT
elif [[ "$PR_TITLE_LOWER" =~ ^feat: ]]; then
echo "Detected new feature - minor version bump"
echo "bump_type=minor" >> $GITHUB_OUTPUT
echo "should_bump=true" >> $GITHUB_OUTPUT
echo "should_build_docker=true" >> $GITHUB_OUTPUT
elif [[ "$PR_TITLE_LOWER" =~ ^(fix|perf|refactor): ]]; then
echo "Detected fix/perf/refactor - patch version bump"
echo "bump_type=patch" >> $GITHUB_OUTPUT
echo "should_bump=true" >> $GITHUB_OUTPUT
echo "should_build_docker=true" >> $GITHUB_OUTPUT
elif [[ "$PR_TITLE_LOWER" =~ ^docker: ]]; then
echo "Detected docker build request - no version bump but build Docker"
echo "bump_type=none" >> $GITHUB_OUTPUT
echo "should_bump=false" >> $GITHUB_OUTPUT
echo "should_build_docker=true" >> $GITHUB_OUTPUT
elif [[ "$PR_TITLE_LOWER" =~ ^(docs|chore|test|ci|style)\+docker: ]]; then
echo "Detected non-versioned change with Docker build request"
echo "bump_type=none" >> $GITHUB_OUTPUT
echo "should_bump=false" >> $GITHUB_OUTPUT
echo "should_build_docker=true" >> $GITHUB_OUTPUT
elif [[ "$PR_TITLE_LOWER" =~ ^(docs|chore|test|ci|style): ]]; then
echo "Detected non-versioned change - no version bump"
echo "bump_type=none" >> $GITHUB_OUTPUT
echo "should_bump=false" >> $GITHUB_OUTPUT
echo "should_build_docker=false" >> $GITHUB_OUTPUT
else
echo "No recognized prefix - no version bump"
echo "bump_type=none" >> $GITHUB_OUTPUT
echo "should_bump=false" >> $GITHUB_OUTPUT
echo "should_build_docker=false" >> $GITHUB_OUTPUT
fi
- name: Get current version
if: steps.bump_type.outputs.should_bump == 'true'
id: current_version
run: |
CURRENT_VERSION=$(python -c "from config import __version__; print(__version__)")
echo "Current version: $CURRENT_VERSION"
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
- name: Bump version
if: steps.bump_type.outputs.should_bump == 'true'
id: new_version
run: |
python scripts/bump_version.py ${{ steps.bump_type.outputs.bump_type }}
NEW_VERSION=$(python -c "from config import __version__; print(__version__)")
echo "New version: $NEW_VERSION"
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Commit version change
if: steps.bump_type.outputs.should_bump == 'true'
run: |
git add config.py
git commit -m "chore: bump version to ${{ steps.new_version.outputs.version }}
Automated version bump from PR #${{ github.event.pull_request.number }}
${{ github.event.pull_request.title }}
Co-authored-by: ${{ github.event.pull_request.user.login }} <${{ github.event.pull_request.user.id }}+${{ github.event.pull_request.user.login }}@users.noreply.github.com>"
git push
- name: Create git tag
if: steps.bump_type.outputs.should_bump == 'true'
run: |
git tag -a "v${{ steps.new_version.outputs.version }}" -m "Release v${{ steps.new_version.outputs.version }}
Changes in this release:
- ${{ github.event.pull_request.title }}
PR: #${{ github.event.pull_request.number }}
Author: @${{ github.event.pull_request.user.login }}"
git push origin "v${{ steps.new_version.outputs.version }}"
- name: Generate release notes
if: steps.bump_type.outputs.should_bump == 'true'
id: release_notes
run: |
# Extract PR body for release notes
PR_BODY=$(cat << 'EOF'
${{ github.event.pull_request.body }}
EOF
)
# Create release notes
RELEASE_NOTES=$(cat << EOF
## What's Changed
${{ github.event.pull_request.title }} by @${{ github.event.pull_request.user.login }} in #${{ github.event.pull_request.number }}
### Details
$PR_BODY
### Version Info
- Previous version: ${{ steps.current_version.outputs.version }}
- New version: ${{ steps.new_version.outputs.version }}
- Bump type: ${{ steps.bump_type.outputs.bump_type }}
**Full Changelog**: https://github.com/${{ github.repository }}/compare/v${{ steps.current_version.outputs.version }}...v${{ steps.new_version.outputs.version }}
EOF
)
# Save to file for GitHub release
echo "$RELEASE_NOTES" > release_notes.md
- name: Create GitHub release
if: steps.bump_type.outputs.should_bump == 'true'
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.new_version.outputs.version }}
name: Release v${{ steps.new_version.outputs.version }}
body_path: release_notes.md
draft: false
prerelease: false
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Trigger Docker build
if: steps.bump_type.outputs.should_build_docker == 'true'
run: |
echo "🐳 Triggering Docker build and publish workflow"
# The Docker workflow will be triggered by the tag creation (if version bumped)
# or by repository_dispatch (if docker: prefix without version bump)
if [ "${{ steps.bump_type.outputs.should_bump }}" == "false" ]; then
# For docker: prefix without version bump, trigger via repository_dispatch
curl -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/dispatches" \
-d '{"event_type":"docker-build","client_payload":{"pr_number":"${{ github.event.pull_request.number }}","pr_title":"${{ github.event.pull_request.title }}","commit_sha":"${{ github.sha }}"}}'
# Add comment to PR about Docker build
COMMENT_BODY="🐳 **Docker Image Build Triggered**
This PR triggered a Docker image build because of the \`+docker\` suffix in the title.
**Expected Image Tags:**
- \`ghcr.io/${{ github.repository_owner }}/zen-mcp-server:pr-${{ github.event.pull_request.number }}\`
- \`ghcr.io/${{ github.repository_owner }}/zen-mcp-server:main-${{ github.sha }}\`
**To test the image after build completes:**
\`\`\`bash
docker pull ghcr.io/${{ github.repository_owner }}/zen-mcp-server:pr-${{ github.event.pull_request.number }}
\`\`\`
**Claude Desktop config for testing:**
\`\`\`json
{
\"mcpServers\": {
\"gemini\": {
\"command\": \"docker\",
\"args\": [
\"run\", \"--rm\", \"-i\",
\"-e\", \"GEMINI_API_KEY\",
\"ghcr.io/${{ github.repository_owner }}/zen-mcp-server:pr-${{ github.event.pull_request.number }}\"
],
\"env\": {
\"GEMINI_API_KEY\": \"your-api-key-here\"
}
}
}
}
\`\`\`
View the build progress in the [Actions tab](https://github.com/${{ github.repository }}/actions)."
curl -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
-d "{\"body\":\"$COMMENT_BODY\"}"
fi
- name: Summary
run: |
if [ "${{ steps.bump_type.outputs.should_bump }}" == "true" ]; then
echo "### ✅ Version Bumped Successfully" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Previous version**: ${{ steps.current_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **New version**: ${{ steps.new_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Bump type**: ${{ steps.bump_type.outputs.bump_type }}" >> $GITHUB_STEP_SUMMARY
echo "- **Tag**: v${{ steps.new_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **PR**: #${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY
echo "- **Docker**: Will build and publish with new tag" >> $GITHUB_STEP_SUMMARY
elif [ "${{ steps.bump_type.outputs.should_build_docker }}" == "true" ]; then
echo "### 🐳 Docker Build Requested" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "No version bump but Docker image will be built and published." >> $GITHUB_STEP_SUMMARY
echo "- **PR**: #${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY
echo "- **Title**: ${{ github.event.pull_request.title }}" >> $GITHUB_STEP_SUMMARY
echo "- **Docker tag**: Based on commit SHA" >> $GITHUB_STEP_SUMMARY
else
echo "### No Version Bump Required" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "PR title prefix did not require a version bump." >> $GITHUB_STEP_SUMMARY
echo "- **PR**: #${{ github.event.pull_request.number }}" >> $GITHUB_STEP_SUMMARY
echo "- **Title**: ${{ github.event.pull_request.title }}" >> $GITHUB_STEP_SUMMARY
fi

View File

@@ -0,0 +1,197 @@
name: Build and Publish Docker Image to GHCR
on:
push:
tags: [ 'v*' ]
repository_dispatch:
types: [docker-build]
env:
REGISTRY: ghcr.io
IMAGE_NAME: beehiveinnovations/zen-mcp-server
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
attestations: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
type=sha,prefix=main-,enable=${{ github.event_name == 'repository_dispatch' }}
type=raw,value=pr-${{ github.event.client_payload.pr_number }},enable=${{ github.event_name == 'repository_dispatch' && github.event.client_payload.pr_number != '' }}
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
- name: Generate usage instructions
run: |
echo "## 🐳 Docker Image Published Successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image Registry:** GitHub Container Registry (GHCR)" >> $GITHUB_STEP_SUMMARY
echo "**Built Tags:** ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Extract the first tag for the main pull command
MAIN_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
echo "### 📥 Pull the Image" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull $MAIN_TAG" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ⚙️ Claude Desktop Configuration" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`json" >> $GITHUB_STEP_SUMMARY
echo "{" >> $GITHUB_STEP_SUMMARY
echo " \"mcpServers\": {" >> $GITHUB_STEP_SUMMARY
echo " \"gemini\": {" >> $GITHUB_STEP_SUMMARY
echo " \"command\": \"docker\"," >> $GITHUB_STEP_SUMMARY
echo " \"args\": [" >> $GITHUB_STEP_SUMMARY
echo " \"run\", \"--rm\", \"-i\"," >> $GITHUB_STEP_SUMMARY
echo " \"-e\", \"GEMINI_API_KEY\"," >> $GITHUB_STEP_SUMMARY
echo " \"$MAIN_TAG\"" >> $GITHUB_STEP_SUMMARY
echo " ]," >> $GITHUB_STEP_SUMMARY
echo " \"env\": {" >> $GITHUB_STEP_SUMMARY
echo " \"GEMINI_API_KEY\": \"your-gemini-api-key-here\"" >> $GITHUB_STEP_SUMMARY
echo " }" >> $GITHUB_STEP_SUMMARY
echo " }" >> $GITHUB_STEP_SUMMARY
echo " }" >> $GITHUB_STEP_SUMMARY
echo "}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🏷️ All Available Tags" >> $GITHUB_STEP_SUMMARY
echo "Built and pushed the following tags:" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" | sed 's/^/- `/' | sed 's/$/`/' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ github.event_name }}" == "repository_dispatch" ]]; then
echo "**Note:** This is a development build triggered by PR #${{ github.event.client_payload.pr_number }}" >> $GITHUB_STEP_SUMMARY
echo "Use this image for testing the changes from that PR." >> $GITHUB_STEP_SUMMARY
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "**Note:** This is a release build from tag ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "This image represents a stable release version." >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 View in GitHub Container Registry" >> $GITHUB_STEP_SUMMARY
echo "[View all versions and tags →](https://github.com/${{ github.repository }}/pkgs/container/zen-mcp-server)" >> $GITHUB_STEP_SUMMARY
- name: Update README with latest image info
if: false # Temporarily disabled as agreed with repo author
# if: github.ref_type == 'tag' || (github.event_name == 'repository_dispatch' && github.event.client_payload.pr_number != '')
run: |
# Checkout main branch to avoid detached HEAD when pushing
git fetch origin main:main
git checkout main
# Extract the primary image tag for updating README
if [[ "${{ github.ref_type }}" == "tag" ]]; then
# For tag releases, use the version tag
LATEST_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}"
UPDATE_TYPE="release"
elif [[ "${{ github.event_name }}" == "repository_dispatch" && "${{ github.event.client_payload.pr_number }}" != "" ]]; then
# For repository_dispatch (PR builds), use the PR tag
LATEST_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.client_payload.pr_number }}"
UPDATE_TYPE="development"
else
# For manual repository_dispatch without PR number, use latest tag
LATEST_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
UPDATE_TYPE="manual"
fi
echo "Updating README.md with latest Docker image: $LATEST_TAG"
# Update README.md with the latest image tag
sed -i.bak "s|ghcr\.io/[^/]*/zen-mcp-server:[a-zA-Z0-9\._-]*|$LATEST_TAG|g" README.md
# Also update docs/user-guides/installation.md
sed -i.bak "s|ghcr\.io/[^/]*/zen-mcp-server:[a-zA-Z0-9\._-]*|$LATEST_TAG|g" docs/user-guides/installation.md
# Also update docs/user-guides/configuration.md
sed -i.bak "s|ghcr\.io/[^/]*/zen-mcp-server:[a-zA-Z0-9\._-]*|$LATEST_TAG|g" docs/user-guides/configuration.md
# Check if there are any changes
if git diff --quiet README.md docs/user-guides/installation.md docs/user-guides/configuration.md; then
echo "No changes needed in documentation"
else
echo "Documentation updated with new image tag"
# Configure git for automated commit
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Add and commit changes
git add README.md docs/user-guides/installation.md docs/user-guides/configuration.md
if [[ "$UPDATE_TYPE" == "release" ]]; then
git commit -m "docs: Update Docker image references to ${{ github.ref_name }}
Automated update after Docker image publish for release ${{ github.ref_name }}.
All documentation now references the latest stable image.
🤖 Automated by GitHub Actions"
elif [[ "$UPDATE_TYPE" == "development" ]]; then
git commit -m "docs: Update Docker image references for PR #${{ github.event.client_payload.pr_number }}
Automated update after Docker image publish for development build.
Documentation updated to reference the latest development image.
🤖 Automated by GitHub Actions"
else
git commit -m "docs: Update Docker image references to latest
Automated update after manual Docker image build.
Documentation updated to reference the latest image.
🤖 Automated by GitHub Actions"
fi
# Push changes back to the repository
git push --set-upstream origin main
echo "### 📝 Documentation Updated" >> $GITHUB_STEP_SUMMARY
echo "README.md and user guides have been automatically updated with the new Docker image tag: \`$LATEST_TAG\`" >> $GITHUB_STEP_SUMMARY
fi

32
.github/workflows/docker-test.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Docker Build Test
on:
pull_request:
branches: [ main ]
jobs:
docker-build-test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Test Docker build
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: test:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build test summary
run: |
echo "### ✅ Docker Build Test Passed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Docker image builds successfully and is ready for production." >> $GITHUB_STEP_SUMMARY

114
scripts/bump_version.py Executable file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""
Version bumping utility for Gemini MCP Server
This script handles semantic version bumping for the project by:
- Reading current version from config.py
- Applying the appropriate version bump (major, minor, patch)
- Updating config.py with new version and timestamp
- Preserving file structure and formatting
"""
import re
import sys
from datetime import datetime
from pathlib import Path
def parse_version(version_string: str) -> tuple[int, int, int]:
"""Parse semantic version string into tuple of integers."""
match = re.match(r"^(\d+)\.(\d+)\.(\d+)", version_string)
if not match:
raise ValueError(f"Invalid version format: {version_string}")
return int(match.group(1)), int(match.group(2)), int(match.group(3))
def bump_version(version: tuple[int, int, int], bump_type: str) -> tuple[int, int, int]:
"""Apply version bump according to semantic versioning rules."""
major, minor, patch = version
if bump_type == "major":
return (major + 1, 0, 0)
elif bump_type == "minor":
return (major, minor + 1, 0)
elif bump_type == "patch":
return (major, minor, patch + 1)
else:
raise ValueError(f"Invalid bump type: {bump_type}")
def update_config_file(new_version: str) -> None:
"""Update version and timestamp in config.py while preserving structure."""
config_path = Path(__file__).parent.parent / "config.py"
if not config_path.exists():
raise FileNotFoundError(f"config.py not found at {config_path}")
# Read the current content
content = config_path.read_text()
# Update version using regex to preserve formatting
version_pattern = r'(__version__\s*=\s*["\'])[\d\.]+(["\'])'
content = re.sub(version_pattern, rf"\g<1>{new_version}\g<2>", content)
# Update the __updated__ field with current date
current_date = datetime.now().strftime("%Y-%m-%d")
updated_pattern = r'(__updated__\s*=\s*["\'])[\d\-]+(["\'])'
content = re.sub(updated_pattern, rf"\g<1>{current_date}\g<2>", content)
# Write back the updated content
config_path.write_text(content)
print(f"Updated config.py: version={new_version}, updated={current_date}")
def get_current_version() -> str:
"""Extract current version from config.py."""
config_path = Path(__file__).parent.parent / "config.py"
if not config_path.exists():
raise FileNotFoundError(f"config.py not found at {config_path}")
content = config_path.read_text()
match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
if not match:
raise ValueError("Could not find __version__ in config.py")
return match.group(1)
def main():
"""Main entry point for version bumping."""
if len(sys.argv) != 2:
print("Usage: python bump_version.py <major|minor|patch>")
sys.exit(1)
bump_type = sys.argv[1].lower()
if bump_type not in ["major", "minor", "patch"]:
print(f"Invalid bump type: {bump_type}")
print("Valid types: major, minor, patch")
sys.exit(1)
try:
# Get current version
current = get_current_version()
print(f"Current version: {current}")
# Parse and bump version
version_tuple = parse_version(current)
new_version_tuple = bump_version(version_tuple, bump_type)
new_version = f"{new_version_tuple[0]}.{new_version_tuple[1]}.{new_version_tuple[2]}"
# Update config file
update_config_file(new_version)
# Output new version for GitHub Actions
print(f"New version: {new_version}")
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()