Publish to PyPI #2505
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Publish to PyPI | |
on: | |
workflow_dispatch: | |
push: | |
branches: | |
- main | |
paths-ignore: | |
- 'llm_dialog_manager/__init__.py' | |
- 'pyproject.toml' | |
# Add these permission settings | |
permissions: | |
contents: write # This allows pushing to the repository | |
pull-requests: write # This allows creating PRs if needed | |
issues: write # This allows creating issues if needed | |
jobs: | |
publish: | |
if: "!contains(github.event.head_commit.message, 'Bump version') && !contains(github.event.head_commit.message, 'bump version')" | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # 需要完整的历史记录以获取所有标签 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.x' | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install build twine setuptools wheel toml | |
- name: Get version from pyproject.toml | |
id: get_version | |
run: | | |
# First verify the file exists and extract version with error handling | |
CURRENT_VERSION=$(python -c ' | |
import toml | |
import sys | |
try: | |
config = toml.load("pyproject.toml") | |
if "project" not in config: | |
print("Error: Missing [project] section in pyproject.toml", file=sys.stderr) | |
sys.exit(1) | |
print(config["project"]["version"]) | |
except Exception as e: | |
print(f"Error: {str(e)}", file=sys.stderr) | |
sys.exit(1) | |
') | |
# Store the version in GitHub Actions output | |
echo "current_version=${CURRENT_VERSION}" >> $GITHUB_OUTPUT | |
# Split version into major, minor, patch components | |
IFS='.' read -r major minor patch <<< "$CURRENT_VERSION" | |
echo "major_version=${major}" >> $GITHUB_OUTPUT | |
echo "minor_version=${minor}" >> $GITHUB_OUTPUT | |
- name: Update version | |
run: | | |
set -e # Exit immediately if a command exits with a non-zero status | |
# Get major and minor version from previous step | |
MAJOR_VERSION="${{ steps.get_version.outputs.major_version }}" | |
MINOR_VERSION="${{ steps.get_version.outputs.minor_version }}" | |
# Find the latest tag matching the current major.minor version | |
VERSION_PREFIX="v${MAJOR_VERSION}.${MINOR_VERSION}." | |
LAST_VERSION_TAG=$(git tag --list "${VERSION_PREFIX}*" --sort=-v:refname | head -n 1) | |
if [ -z "$LAST_VERSION_TAG" ]; then | |
# No tag exists for this major.minor version, start from 1 | |
COMMIT_COUNT=1 | |
else | |
# Count commits since the last version tag | |
COMMIT_COUNT=$(git rev-list ${LAST_VERSION_TAG}..HEAD --count) | |
# Increment commit count to start from the next patch version | |
COMMIT_COUNT=$((COMMIT_COUNT + 1)) | |
fi | |
# Create the new version | |
NEW_VERSION="${MAJOR_VERSION}.${MINOR_VERSION}.${COMMIT_COUNT}" | |
echo "New version will be: ${NEW_VERSION}" | |
# Update version in __init__.py | |
sed -i "s/__version__ = \".*\"/__version__ = \"${NEW_VERSION}\"/" llm_dialog_manager/__init__.py | |
# Update version in pyproject.toml | |
python -c " | |
import toml | |
# Read the current content | |
with open('pyproject.toml', 'r') as f: | |
data = toml.load(f) | |
# Update the version in the project section | |
data['project']['version'] = '${NEW_VERSION}' | |
# Write back to the file | |
with open('pyproject.toml', 'w') as f: | |
toml.dump(data, f) | |
" | |
# Commit the version update | |
git config --local user.email "github-actions[bot]@users.noreply.github.com" | |
git config --local user.name "github-actions[bot]" | |
git add llm_dialog_manager/__init__.py pyproject.toml | |
git commit -m "Bump version to ${NEW_VERSION} [skip ci]" | |
# Tag the new version | |
git tag "v${NEW_VERSION}" | |
# Push changes and tags | |
git push origin main | |
git push origin "v${NEW_VERSION}" | |
- name: Build package | |
run: python -m build | |
- name: Publish to PyPI | |
env: | |
TWINE_USERNAME: __token__ | |
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} | |
run: twine upload dist/* |