feat: streamline GitHub Actions workflows and improve contributor experience
- Replace complex auto-version.yml with simple PR Docker build workflow - Builds Docker images for all PRs using pr-number-sha tagging - Removes redundant versioning logic (semantic-release handles this) - Adds automatic PR comments with Docker usage instructions - Optimize test.yml workflow triggers - Remove redundant push triggers on main branch - Focus on PR testing only for better developer feedback - Add docker-release.yml for production releases - Triggers on GitHub release publication - Multi-platform builds (linux/amd64, linux/arm64) - Updates release notes with Docker installation instructions - Add semantic-release.yml workflow for automated versioning - Uses conventional commits for version bumping - Automatically generates releases and tags - Integrates with Docker workflow via release triggers - Add pre-commit configuration for automatic code quality - Includes ruff (with auto-fix), black, isort - Provides faster development workflow option - Enhance contribution documentation - Add pre-commit hook option as recommended approach - Keep manual script option for comprehensive testing - Improve developer workflow guidance Fixes #215 (automatic changelog generation) Addresses #110 (Docker builds automation) References #107 (improved version tracking) This creates a clean, modern CI/CD pipeline that eliminates redundancy while addressing multiple community requests around changelog generation, Docker builds, and release automation.
This commit is contained in:
289
.github/workflows/auto-version.yml
vendored
289
.github/workflows/auto-version.yml
vendored
@@ -1,248 +1,111 @@
|
||||
name: Auto Version
|
||||
name: PR Docker Build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
branches: [main]
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
version:
|
||||
# Only run if PR was merged (not just closed)
|
||||
if: github.event.pull_request.merged == true
|
||||
docker:
|
||||
name: Build PR Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.PAT }}
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
python-version: '3.9'
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
# PR-specific tag for testing
|
||||
type=raw,value=pr-${{ github.event.number }}-${{ github.sha }}
|
||||
type=raw,value=pr-${{ github.event.number }}
|
||||
|
||||
- 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
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
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 }}
|
||||
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: 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 }}"}}'
|
||||
- name: Comment on PR with Docker info
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
const sha = context.sha.substring(0, 7);
|
||||
const repo = context.repo.repo;
|
||||
const owner = context.repo.owner;
|
||||
|
||||
# Add comment to PR about Docker build
|
||||
COMMENT_BODY="🐳 **Docker Image Build Triggered**
|
||||
const comment = `🐳 **Docker Image Built Successfully**
|
||||
|
||||
This PR triggered a Docker image build because of the \`+docker\` suffix in the title.
|
||||
This PR has been built and pushed as a Docker image for testing:
|
||||
|
||||
**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 }}\`
|
||||
**Available Tags:**
|
||||
- \`ghcr.io/${owner}/${repo}:pr-${prNumber}-${context.sha}\`
|
||||
- \`ghcr.io/${owner}/${repo}:pr-${prNumber}\` (latest for this PR)
|
||||
|
||||
**To test the image after build completes:**
|
||||
**Test the changes:**
|
||||
\`\`\`bash
|
||||
docker pull ghcr.io/${{ github.repository_owner }}/zen-mcp-server:pr-${{ github.event.pull_request.number }}
|
||||
docker pull ghcr.io/${owner}/${repo}:pr-${prNumber}
|
||||
\`\`\`
|
||||
|
||||
**Claude Desktop config for testing:**
|
||||
**Claude Desktop configuration:**
|
||||
\`\`\`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 }}\"
|
||||
"mcpServers": {
|
||||
"zen-mcp-server": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "--rm", "-i",
|
||||
"-e", "GEMINI_API_KEY",
|
||||
"ghcr.io/${owner}/${repo}:pr-${prNumber}"
|
||||
],
|
||||
\"env\": {
|
||||
\"GEMINI_API_KEY\": \"your-api-key-here\"
|
||||
"env": {
|
||||
"GEMINI_API_KEY": "your-api-key-here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
View the build progress in the [Actions tab](https://github.com/${{ github.repository }}/actions)."
|
||||
The image will be updated automatically when you push new commits to this PR.`;
|
||||
|
||||
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
|
||||
github.rest.issues.createComment({
|
||||
issue_number: prNumber,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
body: comment
|
||||
});
|
||||
|
||||
- name: Summary
|
||||
- name: Create deployment summary
|
||||
run: |
|
||||
if [ "${{ steps.bump_type.outputs.should_bump }}" == "true" ]; then
|
||||
echo "### ✅ Version Bumped Successfully" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🐳 PR Docker Build Complete" >> $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
|
||||
|
||||
echo "**PR**: #${{ github.event.number }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Images built:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
116
.github/workflows/docker-release.yml
vendored
Normal file
116
.github/workflows/docker-release.yml
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
name: Docker Release Build
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Tag to build (leave empty for latest release)'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
name: Build and Push Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# If triggered by workflow_dispatch with a tag, checkout that tag
|
||||
ref: ${{ inputs.tag || github.event.release.tag_name }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
# Tag with the release version
|
||||
type=semver,pattern={{version}},value=${{ inputs.tag || github.event.release.tag_name }}
|
||||
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.tag || github.event.release.tag_name }}
|
||||
type=semver,pattern={{major}},value=${{ inputs.tag || github.event.release.tag_name }}
|
||||
# Also tag as latest for the most recent release
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
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: Update release with Docker info
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
RELEASE_TAG="${{ github.event.release.tag_name }}"
|
||||
DOCKER_TAGS=$(echo "${{ steps.meta.outputs.tags }}" | tr '\n' ' ')
|
||||
|
||||
# Add Docker information to the release
|
||||
gh release edit "$RELEASE_TAG" --notes-file - << EOF
|
||||
${{ github.event.release.body }}
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Docker Images
|
||||
|
||||
This release is available as Docker images:
|
||||
|
||||
$(echo "$DOCKER_TAGS" | sed 's/ghcr.io/- `ghcr.io/g' | sed 's/ /`\n/g')
|
||||
|
||||
**Quick start with Docker:**
|
||||
\`\`\`bash
|
||||
docker pull ghcr.io/${{ github.repository }}:$RELEASE_TAG
|
||||
\`\`\`
|
||||
|
||||
**Claude Desktop configuration:**
|
||||
\`\`\`json
|
||||
{
|
||||
"mcpServers": {
|
||||
"zen-mcp-server": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "--rm", "-i",
|
||||
"-e", "GEMINI_API_KEY",
|
||||
"ghcr.io/${{ github.repository }}:$RELEASE_TAG"
|
||||
],
|
||||
"env": {
|
||||
"GEMINI_API_KEY": "your-api-key-here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
EOF
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create deployment summary
|
||||
run: |
|
||||
echo "## 🐳 Docker Release Build Complete" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Release**: ${{ inputs.tag || github.event.release.tag_name }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Images built:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
61
.github/workflows/semantic-release.yml
vendored
Normal file
61
.github/workflows/semantic-release.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: Semantic Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
concurrency: release
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install python-semantic-release
|
||||
|
||||
- name: Verify tests pass
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-dev.txt
|
||||
python -m pytest tests/ -v --ignore=simulator_tests/ -m "not integration"
|
||||
|
||||
- name: Run semantic release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
semantic-release version
|
||||
semantic-release publish
|
||||
|
||||
- name: Upload build artifacts to release
|
||||
if: hashFiles('dist/*') != ''
|
||||
run: |
|
||||
# Get the latest release tag
|
||||
LATEST_TAG=$(gh release list --limit 1 --json tagName --jq '.[0].tagName')
|
||||
if [ ! -z "$LATEST_TAG" ]; then
|
||||
echo "Uploading artifacts to release $LATEST_TAG"
|
||||
gh release upload "$LATEST_TAG" dist/* --clobber
|
||||
fi
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
5
.github/workflows/test.yml
vendored
5
.github/workflows/test.yml
vendored
@@ -1,10 +1,8 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -57,4 +55,3 @@ jobs:
|
||||
|
||||
- name: Run ruff linter
|
||||
run: ruff check . --exclude test_simulation_files
|
||||
|
||||
|
||||
40
.pre-commit-config.yaml
Normal file
40
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
default_stages: [pre-commit, pre-push]
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 25.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
exclude: ^test_simulation_files/
|
||||
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 6.0.1
|
||||
hooks:
|
||||
- id: isort
|
||||
args: ["--profile", "black"]
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.12.8
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix]
|
||||
exclude: ^test_simulation_files/
|
||||
|
||||
# Configuration for specific tools
|
||||
default_language_version:
|
||||
python: python3
|
||||
|
||||
# Exclude patterns
|
||||
exclude: |
|
||||
(?x)^(
|
||||
\.git/|
|
||||
\.venv/|
|
||||
venv/|
|
||||
\.zen_venv/|
|
||||
__pycache__/|
|
||||
\.pytest_cache/|
|
||||
logs/|
|
||||
dist/|
|
||||
build/|
|
||||
test_simulation_files/
|
||||
)$
|
||||
@@ -23,8 +23,16 @@ We maintain high code quality standards. **All contributions must pass our autom
|
||||
|
||||
#### Required Code Quality Checks
|
||||
|
||||
Before submitting any PR, run our automated quality check script:
|
||||
**Option 1 - Automated (Recommended):**
|
||||
```bash
|
||||
# Install pre-commit hooks (one-time setup)
|
||||
pre-commit install
|
||||
|
||||
# Now linting runs automatically on every commit
|
||||
# Includes: ruff (with auto-fix), black, isort
|
||||
```
|
||||
|
||||
**Option 2 - Manual:**
|
||||
```bash
|
||||
# Run the comprehensive quality checks script
|
||||
./code_quality_checks.sh
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "zen-mcp-server"
|
||||
version = "0.1.0"
|
||||
version = "1.1.0"
|
||||
description = "AI-powered MCP server with multiple model providers"
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
@@ -83,6 +83,33 @@ ignore = [
|
||||
"tests/*" = ["B011"]
|
||||
"tests/conftest.py" = ["E402"] # Module level imports not at top of file - needed for test setup
|
||||
|
||||
[tool.semantic_release]
|
||||
version_toml = ["pyproject.toml:project.version"]
|
||||
branch = "main"
|
||||
build_command = "python -m pip install --upgrade build && python -m build"
|
||||
dist_path = "dist/"
|
||||
upload_to_vcs_release = true
|
||||
upload_to_repository = false
|
||||
remove_dist = false
|
||||
commit_version_number = true
|
||||
commit_message = "chore(release): {version}\n\nAutomatically generated by python-semantic-release"
|
||||
tag_format = "v{version}"
|
||||
|
||||
[tool.semantic_release.branches.main]
|
||||
match = "main"
|
||||
prerelease = false
|
||||
|
||||
[tool.semantic_release.changelog]
|
||||
exclude_commit_patterns = []
|
||||
|
||||
[tool.semantic_release.commit_parser_options]
|
||||
allowed_tags = ["build", "chore", "ci", "docs", "feat", "fix", "perf", "style", "refactor", "test"]
|
||||
minor_tags = ["feat"]
|
||||
patch_tags = ["fix", "perf"]
|
||||
|
||||
[tool.semantic_release.remote.token]
|
||||
env = "GH_TOKEN"
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.2"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
@@ -4,3 +4,5 @@ pytest-mock>=3.11.0
|
||||
black>=23.0.0
|
||||
ruff>=0.1.0
|
||||
isort>=5.12.0
|
||||
python-semantic-release>=10.3.0
|
||||
build>=1.0.0
|
||||
|
||||
Reference in New Issue
Block a user