The GitHub release was showing v3.1.3 instead of v3.2.0 because: 1. No explicit `name` was set on the GitHub release action, relying on defaults that could be unreliable 2. The sed command for extracting release notes used unescaped dots in the version regex, which could match wrong versions 3. No fallback if release notes extraction produced an empty file Changes: - Add explicit `name` and `tag_name` to softprops/action-gh-release - Add version consistency check (tag vs pyproject.toml vs package) - Escape dots in sed regex for exact version matching - Add fallback when release notes extraction produces empty output https://claude.ai/code/session_015hYfpKhFH3GSMVSKgA4JVd
122 lines
3.8 KiB
YAML
122 lines
3.8 KiB
YAML
name: Release
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*'
|
||
|
||
permissions:
|
||
contents: write
|
||
|
||
jobs:
|
||
build:
|
||
runs-on: ubuntu-latest
|
||
|
||
steps:
|
||
- uses: actions/checkout@v3
|
||
with:
|
||
submodules: 'recursive'
|
||
|
||
- name: Set up Python
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.10'
|
||
cache: 'pip'
|
||
|
||
- name: Install uv
|
||
run: |
|
||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||
|
||
- name: Install dependencies
|
||
run: |
|
||
python -m pip install --upgrade pip
|
||
pip install -r requirements.txt
|
||
if [ -f skill_seeker_mcp/requirements.txt ]; then pip install -r skill_seeker_mcp/requirements.txt; fi
|
||
# Install package in editable mode for tests (required for src/ layout)
|
||
pip install -e .
|
||
|
||
- name: Run tests
|
||
run: |
|
||
python -m pytest tests/ -v
|
||
|
||
- name: Extract version from tag
|
||
id: get_version
|
||
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
||
|
||
- name: Verify Python version
|
||
run: |
|
||
python --version
|
||
python -c "import sys; assert sys.version_info >= (3, 10), f'Python {sys.version} is not >= 3.10'"
|
||
|
||
- name: Verify version consistency
|
||
run: |
|
||
TAG_VERSION="${{ steps.get_version.outputs.VERSION }}"
|
||
PKG_VERSION=$(python -c "import skill_seekers; print(skill_seekers.__version__)")
|
||
TOML_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
||
echo "Tag version: $TAG_VERSION"
|
||
echo "Package version: $PKG_VERSION"
|
||
echo "TOML version: $TOML_VERSION"
|
||
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
||
echo "::error::Version mismatch! Tag=$TAG_VERSION but package reports=$PKG_VERSION"
|
||
exit 1
|
||
fi
|
||
if [ "$TAG_VERSION" != "$TOML_VERSION" ]; then
|
||
echo "::error::Version mismatch! Tag=$TAG_VERSION but pyproject.toml has=$TOML_VERSION"
|
||
exit 1
|
||
fi
|
||
echo "✅ All versions match: $TAG_VERSION"
|
||
|
||
- name: Create Release Notes
|
||
id: release_notes
|
||
run: |
|
||
if [ -f CHANGELOG.md ]; then
|
||
# Extract changelog for this version (escape dots for exact match)
|
||
VERSION="${{ steps.get_version.outputs.VERSION }}"
|
||
ESCAPED_VERSION=$(echo "$VERSION" | sed 's/\./\\./g')
|
||
sed -n "/## \[${ESCAPED_VERSION}\]/,/## \[/p" CHANGELOG.md | sed '$d' > release_notes.md
|
||
fi
|
||
# Fallback if extraction produced empty file or CHANGELOG.md missing
|
||
if [ ! -s release_notes.md ]; then
|
||
echo "Release v${{ steps.get_version.outputs.VERSION }}" > release_notes.md
|
||
fi
|
||
|
||
- name: Check if release exists
|
||
id: check_release
|
||
run: |
|
||
if gh release view ${{ github.ref_name }} > /dev/null 2>&1; then
|
||
echo "exists=true" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "exists=false" >> $GITHUB_OUTPUT
|
||
fi
|
||
env:
|
||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
- name: Create GitHub Release
|
||
if: steps.check_release.outputs.exists == 'false'
|
||
uses: softprops/action-gh-release@v1
|
||
with:
|
||
name: v${{ steps.get_version.outputs.VERSION }}
|
||
tag_name: ${{ github.ref_name }}
|
||
body_path: release_notes.md
|
||
draft: false
|
||
prerelease: false
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
- name: Skip Release Creation
|
||
if: steps.check_release.outputs.exists == 'true'
|
||
run: |
|
||
echo "ℹ️ Release ${{ github.ref_name }} already exists, skipping creation"
|
||
echo "View at: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
|
||
|
||
- name: Build package
|
||
run: |
|
||
uv build
|
||
|
||
- name: Publish to PyPI
|
||
env:
|
||
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||
run: |
|
||
uv publish --token $UV_PUBLISH_TOKEN
|