2025-06-15 11:34:34 +08:00

450 lines
19 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: Auto Release to PyPI
on:
workflow_dispatch:
inputs:
version_type:
description: 'Version bump type (ignored if custom_version is provided)'
required: false
default: 'patch'
type: choice
options:
- patch # 2.0.0 -> 2.0.1 (bug fixes, security patches, documentation updates)
- minor # 2.0.0 -> 2.1.0 (new features, enhancements, backward-compatible changes)
- major # 2.0.0 -> 3.0.0 (breaking changes, architecture refactoring, API changes)
custom_version:
description: 'Custom version number (e.g., 2.5.0) - overrides version_type if provided'
required: false
type: string
include_desktop:
description: '是否包含桌面應用二進制文件'
required: true
default: true
type: boolean
desktop_build_run_id:
description: '桌面應用構建的 Run ID可選留空使用最新的成功構建'
required: false
type: string
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
- name: Set up Python
run: uv python install
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
uv sync --dev
- name: Configure Git
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Commit dependency changes if any
run: |
if [ -n "$(git status --porcelain)" ]; then
git add .
git commit -m "📦 Update dependencies" || true
fi
- name: Get current version
id: current_version
run: |
CURRENT_VERSION=$(grep '^version =' pyproject.toml | cut -d'"' -f2)
echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "Current version: $CURRENT_VERSION"
- name: Determine new version
id: bump_version
run: |
CUSTOM_VERSION="${{ github.event.inputs.custom_version }}"
if [ -n "$CUSTOM_VERSION" ]; then
echo "🎯 Using custom version: $CUSTOM_VERSION"
# Validate version format (basic semver check)
if [[ ! "$CUSTOM_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Error: Custom version must be in format X.Y.Z (e.g., 2.5.0)"
exit 1
fi
# Update version in pyproject.toml
sed -i "s/^version = \".*\"/version = \"$CUSTOM_VERSION\"/" pyproject.toml
# Update version in .bumpversion.cfg
sed -i "s/^current_version = .*/current_version = $CUSTOM_VERSION/" .bumpversion.cfg
NEW_VERSION="$CUSTOM_VERSION"
echo "✅ Set custom version: $NEW_VERSION"
else
echo "🔄 Using automatic version bump: ${{ github.event.inputs.version_type }}"
uv run bump2version --allow-dirty ${{ github.event.inputs.version_type }}
NEW_VERSION=$(grep '^version =' pyproject.toml | cut -d'"' -f2)
echo "✅ Bumped version to: $NEW_VERSION"
fi
echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "New version: $NEW_VERSION"
- name: Update __init__.py version
run: |
NEW_VERSION="${{ steps.bump_version.outputs.new }}"
sed -i "s/__version__ = \".*\"/__version__ = \"$NEW_VERSION\"/" src/mcp_feedback_enhanced/__init__.py
- name: Extract Release Highlights
id: extract_highlights
run: |
NEW_VERSION="v${{ steps.bump_version.outputs.new }}"
# Extract highlights from English CHANGELOG
if [ -f "RELEASE_NOTES/CHANGELOG.en.md" ]; then
echo "🔍 Extracting highlights for $NEW_VERSION from CHANGELOG..."
# Step 1: Find the version section and extract everything until next version
sed -n "/## \[${NEW_VERSION}\]/,/## \[/p" RELEASE_NOTES/CHANGELOG.en.md | head -n -1 > version_section.txt
# Step 2: Try to extract highlights section
if grep -q "### 🌟 Highlights" version_section.txt; then
echo "📝 Found Highlights section"
sed -n '/### 🌟 Highlights/,/### /p' version_section.txt | head -n -1 | tail -n +2 | grep -E "^[^#]" | head -5 > highlights.txt
elif grep -q "### ✨ New Features" version_section.txt; then
echo "📝 Using New Features section as highlights"
sed -n '/### ✨ New Features/,/### /p' version_section.txt | head -n -1 | tail -n +2 | grep -E "^- " | head -4 > highlights.txt
else
echo "⚠️ No highlights or new features section found"
echo "" > highlights.txt
fi
# Clean up temporary file
rm -f version_section.txt
# Check if we got any content
if [ -s highlights.txt ]; then
echo "✅ Successfully extracted highlights for $NEW_VERSION"
echo "📄 Content preview:"
head -2 highlights.txt
else
echo "⚠️ No highlights extracted, using default content"
echo "- 🚀 New features and improvements" > highlights.txt
echo "- 🐛 Bug fixes and optimizations" >> highlights.txt
fi
else
echo "⚠️ CHANGELOG.en.md not found, using default highlights"
echo "- 🚀 New features and improvements" > highlights.txt
echo "- 🐛 Bug fixes and optimizations" >> highlights.txt
fi
- name: Generate Release Body
id: release_body
run: |
NEW_VERSION="v${{ steps.bump_version.outputs.new }}"
# Get release title from English CHANGELOG
if [ -f "RELEASE_NOTES/CHANGELOG.en.md" ]; then
RELEASE_TITLE=$(grep "## \[${NEW_VERSION}\]" RELEASE_NOTES/CHANGELOG.en.md | head -1 | sed 's/## \[.*\] - //')
fi
if [ -z "$RELEASE_TITLE" ]; then
RELEASE_TITLE="Latest Release"
fi
# Create release body header
echo "# Release ${NEW_VERSION} - ${RELEASE_TITLE}" > release_body.md
echo "" >> release_body.md
echo "## 🌟 Key Highlights" >> release_body.md
# Add highlights
if [ -s highlights.txt ]; then
cat highlights.txt >> release_body.md
else
echo "- 🚀 New features and improvements" >> release_body.md
echo "- 🐛 Bug fixes and optimizations" >> release_body.md
fi
# Add multi-language links section
echo "" >> release_body.md
echo "## 🌐 Detailed Release Notes" >> release_body.md
echo "" >> release_body.md
echo "### 🇺🇸 English" >> release_body.md
echo "📖 **[View Complete English Release Notes](https://github.com/Minidoracat/mcp-feedback-enhanced/blob/main/RELEASE_NOTES/CHANGELOG.en.md)**" >> release_body.md
echo "" >> release_body.md
echo "### 🇹🇼 繁體中文" >> release_body.md
echo "📖 **[查看完整繁體中文發布說明](https://github.com/Minidoracat/mcp-feedback-enhanced/blob/main/RELEASE_NOTES/CHANGELOG.zh-TW.md)**" >> release_body.md
echo "" >> release_body.md
echo "### 🇨🇳 简体中文" >> release_body.md
echo "📖 **[查看完整简体中文发布说明](https://github.com/Minidoracat/mcp-feedback-enhanced/blob/main/RELEASE_NOTES/CHANGELOG.zh-CN.md)**" >> release_body.md
echo "" >> release_body.md
echo "---" >> release_body.md
echo "" >> release_body.md
echo "## 📦 Quick Installation / 快速安裝" >> release_body.md
echo "" >> release_body.md
echo '```bash' >> release_body.md
echo "# Latest version / 最新版本" >> release_body.md
echo "uvx mcp-feedback-enhanced@latest" >> release_body.md
echo "" >> release_body.md
echo "# This specific version / 此特定版本" >> release_body.md
echo "uvx mcp-feedback-enhanced@${NEW_VERSION}" >> release_body.md
echo '```' >> release_body.md
echo "" >> release_body.md
echo "## 🔗 Links" >> release_body.md
echo "- **Documentation**: [README.md](https://github.com/Minidoracat/mcp-feedback-enhanced/blob/main/README.md)" >> release_body.md
echo "- **Full Changelog**: [CHANGELOG](https://github.com/Minidoracat/mcp-feedback-enhanced/blob/main/RELEASE_NOTES/)" >> release_body.md
echo "- **Issues**: [GitHub Issues](https://github.com/Minidoracat/mcp-feedback-enhanced/issues)" >> release_body.md
echo "" >> release_body.md
echo "---" >> release_body.md
echo "**Release automatically generated from CHANGELOG system** 🤖" >> release_body.md
echo "Release body generated successfully"
- name: Verify CHANGELOG Files
run: |
NEW_VERSION="v${{ steps.bump_version.outputs.new }}"
# Check if CHANGELOG files exist and contain the new version
echo "🔍 Verifying CHANGELOG files contain version ${NEW_VERSION}..."
MISSING_FILES=""
if [ -f "RELEASE_NOTES/CHANGELOG.en.md" ]; then
if ! grep -q "\[${NEW_VERSION}\]" "RELEASE_NOTES/CHANGELOG.en.md"; then
echo "⚠️ Warning: ${NEW_VERSION} not found in CHANGELOG.en.md"
MISSING_FILES="${MISSING_FILES} en"
else
echo "✅ Found ${NEW_VERSION} in CHANGELOG.en.md"
fi
else
echo "❌ CHANGELOG.en.md not found"
MISSING_FILES="${MISSING_FILES} en"
fi
if [ -f "RELEASE_NOTES/CHANGELOG.zh-TW.md" ]; then
if ! grep -q "\[${NEW_VERSION}\]" "RELEASE_NOTES/CHANGELOG.zh-TW.md"; then
echo "⚠️ Warning: ${NEW_VERSION} not found in CHANGELOG.zh-TW.md"
MISSING_FILES="${MISSING_FILES} zh-TW"
else
echo "✅ Found ${NEW_VERSION} in CHANGELOG.zh-TW.md"
fi
else
echo "❌ CHANGELOG.zh-TW.md not found"
MISSING_FILES="${MISSING_FILES} zh-TW"
fi
if [ -f "RELEASE_NOTES/CHANGELOG.zh-CN.md" ]; then
if ! grep -q "\[${NEW_VERSION}\]" "RELEASE_NOTES/CHANGELOG.zh-CN.md"; then
echo "⚠️ Warning: ${NEW_VERSION} not found in CHANGELOG.zh-CN.md"
MISSING_FILES="${MISSING_FILES} zh-CN"
else
echo "✅ Found ${NEW_VERSION} in CHANGELOG.zh-CN.md"
fi
else
echo "❌ CHANGELOG.zh-CN.md not found"
MISSING_FILES="${MISSING_FILES} zh-CN"
fi
if [ -n "$MISSING_FILES" ]; then
echo ""
echo "📝 Note: Please ensure CHANGELOG files are updated with version ${NEW_VERSION}"
echo "Missing or incomplete files:${MISSING_FILES}"
echo "The release will continue, but manual CHANGELOG updates may be needed."
else
echo "✅ All CHANGELOG files verified successfully"
fi
- name: Commit version bump
run: |
CUSTOM_VERSION="${{ github.event.inputs.custom_version }}"
VERSION_METHOD=""
if [ -n "$CUSTOM_VERSION" ]; then
VERSION_METHOD="Custom version specified: $CUSTOM_VERSION"
else
VERSION_METHOD="Auto-bumped (${{ github.event.inputs.version_type }})"
fi
git add .
git commit -m "🔖 Release v${{ steps.bump_version.outputs.new }}
- Updated version to ${{ steps.bump_version.outputs.new }}
- $VERSION_METHOD
- Auto-generated release from workflow"
git tag "v${{ steps.bump_version.outputs.new }}"
- name: Download desktop binaries from latest build
if: ${{ github.event.inputs.include_desktop == 'true' }}
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: build-desktop.yml
run_id: ${{ github.event.inputs.desktop_build_run_id }}
path: desktop-artifacts
if_no_artifact_found: warn
- name: Prepare multi-platform desktop binaries
if: ${{ github.event.inputs.include_desktop == 'true' }}
run: |
# 檢查是否有桌面應用構建產物
if [ ! -d "desktop-artifacts" ] || [ -z "$(ls -A desktop-artifacts 2>/dev/null)" ]; then
echo "⚠️ 警告:沒有找到桌面應用構建產物"
echo "💡 提示:請先運行 'Build Desktop Applications' 工作流程"
echo "🔧 或者設置 include_desktop 為 false 來跳過桌面應用"
exit 1
fi
# 創建桌面應用目錄
mkdir -p src/mcp_feedback_enhanced/desktop_release
# 複製所有平台的二進制文件並重命名
echo "📦 準備多平台桌面應用二進制文件..."
# 檢查並複製各平台文件
if [ -f "desktop-artifacts/desktop-windows/mcp-feedback-enhanced-desktop.exe" ]; then
cp desktop-artifacts/desktop-windows/mcp-feedback-enhanced-desktop.exe src/mcp_feedback_enhanced/desktop_release/
echo "✅ Windows 二進制文件已複製"
else
echo "⚠️ Windows 二進制文件不存在"
fi
if [ -f "desktop-artifacts/desktop-macos-intel/mcp-feedback-enhanced-desktop" ]; then
cp desktop-artifacts/desktop-macos-intel/mcp-feedback-enhanced-desktop src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-macos-intel
echo "✅ macOS Intel 二進制文件已複製"
else
echo "⚠️ macOS Intel 二進制文件不存在"
fi
if [ -f "desktop-artifacts/desktop-macos-arm64/mcp-feedback-enhanced-desktop" ]; then
cp desktop-artifacts/desktop-macos-arm64/mcp-feedback-enhanced-desktop src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-macos-arm64
echo "✅ macOS ARM64 二進制文件已複製"
else
echo "⚠️ macOS ARM64 二進制文件不存在"
fi
if [ -f "desktop-artifacts/desktop-linux/mcp-feedback-enhanced-desktop" ]; then
cp desktop-artifacts/desktop-linux/mcp-feedback-enhanced-desktop src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-linux
echo "✅ Linux 二進制文件已複製"
else
echo "⚠️ Linux 二進制文件不存在"
fi
# 設置執行權限
chmod +x src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-* 2>/dev/null || true
# 創建 __init__.py
echo '"""桌面應用程式二進制檔案"""' > src/mcp_feedback_enhanced/desktop_release/__init__.py
# 顯示文件列表
echo "📦 最終的桌面應用二進制文件:"
ls -la src/mcp_feedback_enhanced/desktop_release/
- name: Build desktop applications locally (fallback)
if: ${{ github.event.inputs.include_desktop == 'true' }}
run: |
# 如果沒有預構建的桌面應用,嘗試本地構建
if [ ! -d "src/mcp_feedback_enhanced/desktop_release" ] || [ -z "$(ls -A src/mcp_feedback_enhanced/desktop_release 2>/dev/null)" ]; then
echo "🔧 沒有找到預構建的桌面應用,嘗試本地構建..."
echo "⚠️ 注意:本地構建可能只支援當前平台"
# 安裝 Rust如果還沒安裝
if ! command -v cargo &> /dev/null; then
echo "📦 安裝 Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source ~/.cargo/env
fi
# 運行本地構建腳本
python scripts/build_desktop.py --release
echo "✅ 本地桌面應用構建完成"
else
echo "✅ 使用預構建的桌面應用"
fi
- name: Skip desktop applications
if: ${{ github.event.inputs.include_desktop != 'true' }}
run: |
echo "⏭️ 跳過桌面應用,僅發佈 Web 版本"
echo "💡 用戶將只能使用 Web 模式,無法使用桌面模式"
- name: Build package
run: uv build
- name: Check package
run: uv run twine check dist/*
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Push changes and tags
run: |
git push origin main
git push origin "v${{ steps.bump_version.outputs.new }}"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: "v${{ steps.bump_version.outputs.new }}"
name: "Release v${{ steps.bump_version.outputs.new }}"
body_path: release_body.md
draft: false
prerelease: false
generate_release_notes: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Summary
run: |
echo "🎉 Release v${{ steps.bump_version.outputs.new }} completed successfully!"
echo ""
echo "📦 Published to PyPI: https://pypi.org/project/mcp-feedback-enhanced/"
echo "🚀 GitHub Release: https://github.com/Minidoracat/mcp-feedback-enhanced/releases/tag/v${{ steps.bump_version.outputs.new }}"
echo "📝 Release notes generated from CHANGELOG files"
echo ""
# 顯示桌面應用狀態
if [ "${{ github.event.inputs.include_desktop }}" = "true" ]; then
echo "🖥️ 桌面應用狀態:"
if [ -d "src/mcp_feedback_enhanced/desktop_release" ] && [ -n "$(ls -A src/mcp_feedback_enhanced/desktop_release 2>/dev/null)" ]; then
echo " ✅ 桌面應用已包含在發佈中"
echo " 📱 支援的平台:"
[ -f "src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop.exe" ] && echo " - Windows x64"
[ -f "src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-macos-intel" ] && echo " - macOS Intel"
[ -f "src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-macos-arm64" ] && echo " - macOS Apple Silicon"
[ -f "src/mcp_feedback_enhanced/desktop_release/mcp-feedback-enhanced-desktop-linux" ] && echo " - Linux x64"
else
echo " ⚠️ 桌面應用未包含(可能構建失敗)"
fi
else
echo "🖥️ 桌面應用狀態:⏭️ 已跳過(僅 Web 版本)"
fi
echo ""
echo "✅ Next steps:"
echo " - Check the release on GitHub"
echo " - Verify the package on PyPI"
echo " - Test installation with: uvx mcp-feedback-enhanced@v${{ steps.bump_version.outputs.new }}"
if [ "${{ github.event.inputs.include_desktop }}" = "true" ]; then
echo " - Test desktop mode with: uvx mcp-feedback-enhanced@v${{ steps.bump_version.outputs.new }} test --desktop"
fi
echo ""
echo "📋 Note: Make sure CHANGELOG files are updated for future releases"