diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bdb071ac..dc7544cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,39 +13,46 @@ on: jobs: release: runs-on: ubuntu-latest - + environment: pypi + permissions: contents: write pull-requests: write - + id-token: write + steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + - name: Get latest tag id: get_tag run: | # Get the latest tag, or use v0.0.0 if no tags exist LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT - + # Extract version number and increment VERSION=$(echo $LATEST_TAG | sed 's/v//') IFS='.' read -ra VERSION_PARTS <<< "$VERSION" MAJOR=${VERSION_PARTS[0]:-0} MINOR=${VERSION_PARTS[1]:-0} PATCH=${VERSION_PARTS[2]:-0} - + # Increment patch version PATCH=$((PATCH + 1)) NEW_VERSION="v$MAJOR.$MINOR.$PATCH" - + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT echo "New version will be: $NEW_VERSION" - + - name: Check if release already exists id: check_release run: | @@ -58,13 +65,32 @@ jobs: fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + - name: Create release package if: steps.check_release.outputs.exists == 'false' run: | chmod +x .github/workflows/scripts/create-release-packages.sh .github/workflows/scripts/create-release-packages.sh ${{ steps.get_tag.outputs.new_version }} - + + - name: Update version in pyproject.toml + if: steps.check_release.outputs.exists == 'false' + run: | + # Update version in pyproject.toml (remove 'v' prefix for Python versioning) + VERSION=${{ steps.get_tag.outputs.new_version }} + PYTHON_VERSION=${VERSION#v} + + if [ -f "pyproject.toml" ]; then + sed -i "s/version = \".*\"/version = \"$PYTHON_VERSION\"/" pyproject.toml + echo "Updated pyproject.toml version to $PYTHON_VERSION" + fi + + - name: Build Python package + if: steps.check_release.outputs.exists == 'false' + run: | + uv build + echo "Built Python package:" + ls -la dist/ + - name: Generate release notes if: steps.check_release.outputs.exists == 'false' id: release_notes @@ -82,49 +108,68 @@ jobs: else COMMITS=$(git log --oneline --pretty=format:"- %s" $LAST_TAG..HEAD) fi - + # Create release notes + VERSION_NO_V=${{ steps.get_tag.outputs.new_version }} + VERSION_NO_V=${VERSION_NO_V#v} + cat > release_notes.md << EOF Template release ${{ steps.get_tag.outputs.new_version }} - + Updated specification-driven development templates for GitHub Copilot, Claude Code, and Gemini CLI. - + + ## Installation + + **Via PyPI (Recommended):** + \`\`\`bash + uvx --from specify-cli specify init + # or + pip install specify-cli + specify init + \`\`\` + + **Via Git:** + \`\`\`bash + uvx --from git+https://github.com/github/spec-kit.git specify init + \`\`\` + + ## Template Downloads + Download the template for your preferred AI assistant: - spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip - spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip - - spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip + - spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip + + ## Python Package Files + + Python wheel and source distribution files are also included in this release for direct installation. EOF - + echo "Generated release notes:" cat release_notes.md - + + - name: Publish to PyPI + if: steps.check_release.outputs.exists == 'false' + run: | + uv publish + - name: Create GitHub Release if: steps.check_release.outputs.exists == 'false' run: | # Remove 'v' prefix from version for release title VERSION_NO_V=${{ steps.get_tag.outputs.new_version }} VERSION_NO_V=${VERSION_NO_V#v} - + gh release create ${{ steps.get_tag.outputs.new_version }} \ spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip \ spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip \ spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip \ + dist/*.whl \ + dist/*.tar.gz \ --title "Spec Kit Templates - $VERSION_NO_V" \ --notes-file release_notes.md env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Update version in pyproject.toml (for release artifacts only) - if: steps.check_release.outputs.exists == 'false' - run: | - # Update version in pyproject.toml (remove 'v' prefix for Python versioning) - VERSION=${{ steps.get_tag.outputs.new_version }} - PYTHON_VERSION=${VERSION#v} - - if [ -f "pyproject.toml" ]; then - sed -i "s/version = \".*\"/version = \"$PYTHON_VERSION\"/" pyproject.toml - echo "Updated pyproject.toml version to $PYTHON_VERSION (for release artifacts only)" - fi - + # Note: No longer committing version changes back to main branch - # The version is only updated in the release artifacts + # The version is only updated in the release artifacts and published to PyPI diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..902b2c90 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11 \ No newline at end of file diff --git a/README.md b/README.md index a456a161..80cf9f42 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,14 @@ Spec-Driven Development **flips the script** on traditional software development Initialize your project depending on the coding agent you're using: ```bash +# Recommended: Install from PyPI +uvx --from specify-cli specify init + +# Install from PyPI with pip +pip install specify-cli +specify init + +# Alternative: Install from Git uvx --from git+https://github.com/github/spec-kit.git specify init ```