Merge development into main: fix release workflow timeout #44
Workflow file for this run
This file contains hidden or 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: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| 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 | |
| timeout-minutes: 30 | |
| run: | | |
| # Exclude slow MCP/e2e tests that can hang or run 20+ min each. | |
| # The tests.yml workflow (matrix CI) runs these in a separate job with | |
| # its own timeout; the release workflow only needs fast confidence that | |
| # the package is sound before publishing. | |
| python -m pytest tests/ -v \ | |
| --ignore=tests/test_mcp_fastmcp.py \ | |
| --ignore=tests/test_mcp_server.py \ | |
| --ignore=tests/test_install_skill_e2e.py \ | |
| --ignore=tests/test_bootstrap_skill_e2e.py | |
| - 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=$(grep -m1 '^version' pyproject.toml | sed 's/version *= *"\(.*\)"/\1/') | |
| 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 |