From a8b91d51eba9deea51c05520a63b4f4d907fc106 Mon Sep 17 00:00:00 2001 From: abdulgeek Date: Thu, 30 Apr 2026 11:53:17 +0530 Subject: [PATCH] fix(release): sync 2.5.7 with PyPI; safe Auto Release / Version Bump - Bump setup.py, __version__, User-Agent; CHANGELOG [2.5.7]. - Auto Release: workflow_dispatch only; PyPI after successful git push; RELEASE_PUSH_TOKEN optional for protected master. - Version Bump: workflow_dispatch only; update client UA; PAT for push; drop redundant publish dispatch. --- .github/workflows/auto-release.yml | 84 +++++++++++------------------- .github/workflows/version-bump.yml | 40 ++++---------- CHANGELOG.md | 8 +++ cost_katana/__init__.py | 2 +- cost_katana/client.py | 2 +- setup.py | 2 +- 6 files changed, 51 insertions(+), 87 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 535bdec..0599be1 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -1,12 +1,10 @@ -name: Auto Release on Push +# Manual patch release: bump version, push to default branch + tag, then PyPI + GitHub Release. +# `master` is often protected — set secret RELEASE_PUSH_TOKEN (PAT with contents:write + bypass) +# or use PR + tag flow via publish.yml instead of this workflow. +name: Auto Release on: - push: - branches: [ main, master ] - paths-ignore: - - '**.md' - - '.github/**' - - 'CHANGELOG.md' + workflow_dispatch: jobs: auto-release: @@ -19,9 +17,6 @@ jobs: with: fetch-depth: 0 ssh-strict: false - # Omit token: uses repo default GITHUB_TOKEN (same as github.token). - # Optional PAT secret AI_GITHUB_TOKEN with contents:write if pushes must - # trigger other workflows (GITHUB_TOKEN pushes skip downstream workflows). - name: Set up Python uses: actions/setup-python@v4 @@ -65,13 +60,11 @@ jobs: run: | CURRENT_VERSION="${{ steps.current_version.outputs.current_version }}" - # Split version into components IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION" MAJOR="${VERSION_PARTS[0]}" MINOR="${VERSION_PARTS[1]}" PATCH="${VERSION_PARTS[2]}" - # Always bump patch version for auto-releases NEW_MAJOR=$MAJOR NEW_MINOR=$MINOR NEW_PATCH=$((PATCH + 1)) @@ -80,64 +73,57 @@ jobs: echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT echo "New version: $NEW_VERSION" - - name: Update version in setup.py and package __init__.py + - name: Update version in setup.py, __init__.py, and client User-Agent run: | NEW="${{ steps.new_version.outputs.new_version }}" sed -i "s/version=\"[^\"]*\"/version=\"${NEW}\"/" setup.py sed -i "s/__version__ = \"[^\"]*\"/__version__ = \"${NEW}\"/" cost_katana/__init__.py - echo "Updated version to ${NEW}" + sed -i "s/cost-katana-python\/[0-9.]*\"/cost-katana-python\/${NEW}\"/" cost_katana/client.py - name: Build package run: | rm -rf dist build cost_katana.egg-info python setup.py sdist bdist_wheel - # Same secret name as publish.yml and manual-release.yml - - name: Publish to PyPI + - name: Create and push commit and tag env: - PYPI_SECRET: ${{ secrets.PYPI_API_TOKEN }} - run: | - if [ -z "$PYPI_SECRET" ]; then - echo "::error::Add repository secret PYPI_API_TOKEN (PyPI API token with upload scope)." - exit 1 - fi - echo "[pypi]" > ~/.pypirc - echo "username = __token__" >> ~/.pypirc - echo "password = $PYPI_SECRET" >> ~/.pypirc - python -m twine upload --repository pypi dist/* - echo "Successfully published cost-katana@${{ steps.new_version.outputs.new_version }} to PyPI" - - - name: Create and push tag + # PAT optional: bypass protected-branch pushes; otherwise falls back to github.token (often blocked on master). + PUSH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN || github.token }} run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" + git remote set-url origin "https://x-access-token:${PUSH_TOKEN}@github.com/${{ github.repository }}.git" - # Configure git to use the token for authentication - git remote set-url origin https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git - - # Verify the remote URL is set correctly - echo "Remote URL: $(git remote get-url origin)" - - # Add and commit changes - git add setup.py cost_katana/__init__.py + git add setup.py cost_katana/__init__.py cost_katana/client.py git commit -m "Auto-release: Bump version to ${{ steps.new_version.outputs.new_version }}" - - # Create tag git tag -a "v${{ steps.new_version.outputs.new_version }}" -m "Auto-release version ${{ steps.new_version.outputs.new_version }}" - # Push with explicit authentication - if ! git push origin HEAD:${{ github.ref }}; then + if ! git push origin "HEAD:${{ github.ref }}"; then echo "Git push failed, trying with GitHub CLI..." - gh auth login --with-token <<< "${{ github.token }}" - git push origin HEAD:${{ github.ref }} + echo "$PUSH_TOKEN" | gh auth login --with-token + git push origin "HEAD:${{ github.ref }}" fi if ! git push origin "v${{ steps.new_version.outputs.new_version }}"; then echo "Tag push failed, trying with GitHub CLI..." - gh auth login --with-token <<< "${{ github.token }}" + echo "$PUSH_TOKEN" | gh auth login --with-token git push origin "v${{ steps.new_version.outputs.new_version }}" fi + - name: Publish to PyPI + env: + PYPI_SECRET: ${{ secrets.PYPI_API_TOKEN }} + run: | + if [ -z "$PYPI_SECRET" ]; then + echo "::error::Add repository secret PYPI_API_TOKEN (PyPI API token with upload scope)." + exit 1 + fi + echo "[pypi]" > ~/.pypirc + echo "username = __token__" >> ~/.pypirc + echo "password = $PYPI_SECRET" >> ~/.pypirc + python -m twine upload --repository pypi dist/* + echo "Successfully published cost-katana@${{ steps.new_version.outputs.new_version }} to PyPI" + - name: Create GitHub Release uses: actions/create-release@v1 env: @@ -148,17 +134,9 @@ jobs: body: | ## Auto-release v${{ steps.new_version.outputs.new_version }} - This is an automatic release triggered by changes to the main branch. - ### Installation ```bash pip install cost-katana==${{ steps.new_version.outputs.new_version }} ``` - - ### Changes - - Automatic version bump and release - - Updated dependencies and improvements - - Enhanced Python package structure - - Better error handling draft: false - prerelease: false \ No newline at end of file + prerelease: false diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml index 0b1d802..89c1f90 100644 --- a/.github/workflows/version-bump.yml +++ b/.github/workflows/version-bump.yml @@ -12,11 +12,6 @@ on: - patch - minor - major - push: - branches: [ main, master ] - paths-ignore: - - '**.md' - - '.github/**' jobs: version-bump: @@ -24,14 +19,11 @@ jobs: timeout-minutes: 10 permissions: contents: write - actions: write - if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - # Uses default GITHUB_TOKEN from checkout for subsequent git push. - name: Set up Python uses: actions/setup-python@v4 @@ -53,15 +45,9 @@ jobs: - name: Calculate new version id: new_version run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - BUMP_TYPE="${{ github.event.inputs.bump_type }}" - else - BUMP_TYPE="patch" - fi - + BUMP_TYPE="${{ github.event.inputs.bump_type }}" CURRENT_VERSION="${{ steps.current_version.outputs.current_version }}" - # Split version into components IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION" MAJOR="${VERSION_PARTS[0]}" MINOR="${VERSION_PARTS[1]}" @@ -89,31 +75,23 @@ jobs: echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT echo "New version: $NEW_VERSION" - - name: Update version in setup.py and package __init__.py + - name: Update version in setup.py, __init__.py, and client User-Agent run: | OLD="${{ steps.current_version.outputs.current_version }}" NEW="${{ steps.new_version.outputs.new_version }}" sed -i "s/version=\"${OLD}\"/version=\"${NEW}\"/" setup.py sed -i "s/__version__ = \"${OLD}\"/__version__ = \"${NEW}\"/" cost_katana/__init__.py - echo "Updated version to ${NEW}" + sed -i "s/cost-katana-python\/${OLD}\"/cost-katana-python\/${NEW}\"/" cost_katana/client.py - - name: Create and push tag + - name: Create and push commit and tag + env: + PUSH_TOKEN: ${{ secrets.RELEASE_PUSH_TOKEN || github.token }} run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - git add setup.py cost_katana/__init__.py + git remote set-url origin "https://x-access-token:${PUSH_TOKEN}@github.com/${{ github.repository }}.git" + git add setup.py cost_katana/__init__.py cost_katana/client.py git commit -m "Bump version to ${{ steps.new_version.outputs.new_version }}" git tag -a "v${{ steps.new_version.outputs.new_version }}" -m "Release version ${{ steps.new_version.outputs.new_version }}" - git push origin HEAD:${{ github.ref }} + git push origin "HEAD:${{ github.ref }}" git push origin "v${{ steps.new_version.outputs.new_version }}" - - - name: Trigger publish workflow - uses: actions/github-script@v7 - with: - script: | - github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: context.repo.repo, - workflow_id: 'publish.yml', - ref: context.ref - }) \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9963fe5..05f059d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to Cost Katana Python SDK will be documented in this file. ## [Unreleased] +## [2.5.7] - 2026-04-30 + +### Fixed + +- **Source ↔ PyPI**: Align repo metadata with **2.5.7** already on PyPI after an Auto Release run could upload but not push to protected `master`. +- **Auto Release**: Workflow is **`workflow_dispatch` only**; **PyPI upload runs only after** commit + tag push succeed; bumps **`cost_katana/client.py`** User-Agent; optional secret **`RELEASE_PUSH_TOKEN`** (PAT with `contents:write` and branch bypass) when `github.token` cannot push `master`. +- **Version Bump**: **`workflow_dispatch` only** (no push hook); same **`RELEASE_PUSH_TOKEN`** / User-Agent handling; redundant **`publish.yml` dispatch** removed — tag push triggers **Build and Publish**. + ## [2.5.6] - 2026-04-29 ### Fixed diff --git a/cost_katana/__init__.py b/cost_katana/__init__.py index e0912d7..1058d9c 100644 --- a/cost_katana/__init__.py +++ b/cost_katana/__init__.py @@ -56,7 +56,7 @@ get_provider_from_model, ) -__version__ = "2.5.6" +__version__ = "2.5.7" def track(entry: Dict[str, Any]) -> None: diff --git a/cost_katana/client.py b/cost_katana/client.py index f87f728..261c549 100644 --- a/cost_katana/client.py +++ b/cost_katana/client.py @@ -170,7 +170,7 @@ def __init__( headers: Dict[str, str] = { "Authorization": f"Bearer {self.config.api_key}", "Content-Type": "application/json", - "User-Agent": "cost-katana-python/2.5.6", + "User-Agent": "cost-katana-python/2.5.7", } if self.config.project_id: headers["x-project-id"] = self.config.project_id diff --git a/setup.py b/setup.py index 777b3d7..3c38540 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setup( name="cost-katana", - version="2.5.6", + version="2.5.7", author="Cost Katana Team", author_email="support@costkatana.com", description="The simplest way to use AI in Python with automatic cost tracking and optimization",